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
.Generic
;
16 using System
.Reflection
;
17 using System
.Reflection
.Emit
;
18 using System
.Runtime
.CompilerServices
;
19 using System
.Runtime
.InteropServices
;
20 using System
.Security
;
21 using System
.Security
.Permissions
;
25 using XmlElement
= System
.Object
;
30 using Mono
.CompilerServices
.SymbolWriter
;
32 namespace Mono
.CSharp
{
35 /// This is the base class for structs and classes.
37 public abstract class TypeContainer
: DeclSpace
, IMemberContainer
40 // Different context is needed when resolving type container base
41 // types. Type names come from the parent scope but type parameter
42 // names from the container scope.
44 struct BaseContext
: IMemberContext
48 public BaseContext (TypeContainer tc
)
53 #region IMemberContext Members
55 public CompilerContext Compiler
{
56 get { return tc.Compiler; }
59 public Type CurrentType
{
60 get { return tc.Parent.CurrentType; }
63 public TypeParameter
[] CurrentTypeParameters
{
64 get { return tc.PartialContainer.CurrentTypeParameters; }
67 public TypeContainer CurrentTypeDefinition
{
68 get { return tc.Parent.CurrentTypeDefinition; }
71 public bool IsObsolete
{
72 get { return tc.IsObsolete; }
75 public bool IsUnsafe
{
76 get { return tc.IsUnsafe; }
79 public bool IsStatic
{
80 get { return tc.IsStatic; }
83 public string GetSignatureForError ()
85 throw new NotImplementedException ();
88 public ExtensionMethodGroupExpr
LookupExtensionMethod (Type extensionType
, string name
, Location loc
)
93 public FullNamedExpression
LookupNamespaceAlias (string name
)
95 return tc
.Parent
.LookupNamespaceAlias (name
);
98 public FullNamedExpression
LookupNamespaceOrType (string name
, Location loc
, bool ignore_cs0104
)
100 TypeParameter
[] tp
= CurrentTypeParameters
;
102 TypeParameter t
= TypeParameter
.FindTypeParameter (tp
, name
);
104 return new TypeParameterExpr (t
, loc
);
107 return tc
.Parent
.LookupNamespaceOrType (name
, loc
, ignore_cs0104
);
117 GetHashCode
= 1 << 1,
118 HasStaticFieldInitializer
= 1 << 2
122 // Whether this is a struct, class or interface
123 public readonly MemberKind Kind
;
125 // Holds a list of classes and structures
126 protected List
<TypeContainer
> types
;
128 List
<MemberCore
> ordered_explicit_member_list
;
129 List
<MemberCore
> ordered_member_list
;
131 // Holds the list of properties
132 List
<MemberCore
> properties
;
134 // Holds the list of delegates
135 List
<TypeContainer
> delegates
;
137 // Holds the list of constructors
138 protected List
<MemberCore
> instance_constructors
;
140 // Holds the list of fields
141 protected List
<MemberCore
> fields
;
143 // Holds a list of fields that have initializers
144 protected List
<FieldInitializer
> initialized_fields
;
146 // Holds a list of static fields that have initializers
147 protected List
<FieldInitializer
> initialized_static_fields
;
149 // Holds the list of constants
150 protected List
<MemberCore
> constants
;
152 // Holds the methods.
153 List
<MemberCore
> methods
;
156 protected List
<MemberCore
> events
;
158 // Holds the indexers
159 List
<MemberCore
> indexers
;
161 // Holds the operators
162 List
<MemberCore
> operators
;
164 // Holds the compiler generated classes
165 List
<CompilerGeneratedClass
> compiler_generated
;
168 // Pointers to the default constructor and the default static constructor
170 protected Constructor default_constructor
;
171 protected Constructor default_static_constructor
;
174 // Points to the first non-static field added to the container.
176 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
177 // and the first one's as good as any.
179 FieldBase first_nonstatic_field
= null;
182 // This one is computed after we can distinguish interfaces
183 // from classes from the arraylist `type_bases'
186 TypeExpr
[] iface_exprs
;
188 GenericTypeParameterBuilder
[] nested_gen_params
;
190 protected List
<FullNamedExpression
> type_bases
;
192 protected bool members_defined
;
193 bool members_defined_ok
;
195 // The interfaces we implement.
196 protected Type
[] ifaces
;
198 // The base member cache and our member cache
199 MemberCache base_cache
;
200 protected MemberCache member_cache
;
202 public const string DefaultIndexerName
= "Item";
204 private bool seen_normal_indexers
= false;
205 private string indexer_name
= DefaultIndexerName
;
206 protected bool requires_delayed_unmanagedtype_check
;
208 private CachedMethods cached_method
;
210 List
<TypeContainer
> partial_parts
;
213 /// The pending methods that need to be implemented
214 // (interfaces or abstract methods)
216 PendingImplementation pending
;
218 public TypeContainer (NamespaceEntry ns
, DeclSpace parent
, MemberName name
,
219 Attributes attrs
, MemberKind kind
)
220 : base (ns
, parent
, name
, attrs
)
222 if (parent
!= null && parent
.NamespaceEntry
!= ns
)
223 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
226 this.PartialContainer
= this;
229 public bool AddMember (MemberCore symbol
)
231 return AddToContainer (symbol
, symbol
.MemberName
.Basename
);
234 protected virtual bool AddMemberType (DeclSpace ds
)
236 return AddToContainer (ds
, ds
.Basename
);
239 protected virtual void RemoveMemberType (DeclSpace ds
)
241 RemoveFromContainer (ds
.Basename
);
244 public void AddConstant (Const constant
)
246 if (!AddMember (constant
))
249 if (constants
== null)
250 constants
= new List
<MemberCore
> ();
252 constants
.Add (constant
);
255 public TypeContainer
AddTypeContainer (TypeContainer tc
)
257 if (!AddMemberType (tc
))
261 types
= new List
<TypeContainer
> ();
267 public virtual TypeContainer
AddPartial (TypeContainer next_part
)
269 return AddPartial (next_part
, next_part
.Basename
);
272 protected TypeContainer
AddPartial (TypeContainer next_part
, string name
)
274 next_part
.ModFlags
|= Modifiers
.PARTIAL
;
275 TypeContainer tc
= GetDefinition (name
) as TypeContainer
;
277 return AddTypeContainer (next_part
);
279 if ((tc
.ModFlags
& Modifiers
.PARTIAL
) == 0) {
280 Report
.SymbolRelatedToPreviousError (next_part
);
281 Error_MissingPartialModifier (tc
);
284 if (tc
.Kind
!= next_part
.Kind
) {
285 Report
.SymbolRelatedToPreviousError (tc
);
286 Report
.Error (261, next_part
.Location
,
287 "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
288 next_part
.GetSignatureForError ());
291 if ((tc
.ModFlags
& Modifiers
.AccessibilityMask
) != (next_part
.ModFlags
& Modifiers
.AccessibilityMask
) &&
292 ((tc
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) == 0 &&
293 (next_part
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) == 0)) {
294 Report
.SymbolRelatedToPreviousError (tc
);
295 Report
.Error (262, next_part
.Location
,
296 "Partial declarations of `{0}' have conflicting accessibility modifiers",
297 next_part
.GetSignatureForError ());
300 if (tc
.partial_parts
== null)
301 tc
.partial_parts
= new List
<TypeContainer
> (1);
303 if ((next_part
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) != 0) {
304 tc
.ModFlags
|= next_part
.ModFlags
& ~
(Modifiers
.DEFAULT_ACCESS_MODIFER
| Modifiers
.AccessibilityMask
);
305 } else if ((tc
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) != 0) {
306 tc
.ModFlags
&= ~
(Modifiers
.DEFAULT_ACCESS_MODIFER
| Modifiers
.AccessibilityMask
);
307 tc
.ModFlags
|= next_part
.ModFlags
;
309 tc
.ModFlags
|= next_part
.ModFlags
;
312 if (next_part
.attributes
!= null) {
313 if (tc
.attributes
== null)
314 tc
.attributes
= next_part
.attributes
;
316 tc
.attributes
.AddAttributes (next_part
.attributes
.Attrs
);
319 next_part
.PartialContainer
= tc
;
320 tc
.partial_parts
.Add (next_part
);
324 public virtual void RemoveTypeContainer (TypeContainer next_part
)
327 types
.Remove (next_part
);
328 RemoveMemberType (next_part
);
331 public void AddDelegate (Delegate d
)
333 if (!AddMemberType (d
))
336 if (delegates
== null)
337 delegates
= new List
<TypeContainer
> ();
342 private void AddMemberToList (MemberCore mc
, List
<MemberCore
> alist
, bool isexplicit
)
344 if (ordered_explicit_member_list
== null) {
345 ordered_explicit_member_list
= new List
<MemberCore
> ();
346 ordered_member_list
= new List
<MemberCore
> ();
350 if (Kind
== MemberKind
.Interface
) {
351 Report
.Error (541, mc
.Location
,
352 "`{0}': explicit interface declaration can only be declared in a class or struct",
353 mc
.GetSignatureForError ());
356 ordered_explicit_member_list
.Add (mc
);
357 alist
.Insert (0, mc
);
359 ordered_member_list
.Add (mc
);
365 public void AddMethod (MethodOrOperator method
)
367 if (!AddToContainer (method
, method
.MemberName
.Basename
))
371 methods
= new List
<MemberCore
> ();
373 if (method
.MemberName
.Left
!= null)
374 AddMemberToList (method
, methods
, true);
376 AddMemberToList (method
, methods
, false);
379 public void AddConstructor (Constructor c
)
381 bool is_static
= (c
.ModFlags
& Modifiers
.STATIC
) != 0;
382 if (!AddToContainer (c
, is_static
?
383 ConstructorBuilder
.ConstructorName
: ConstructorBuilder
.TypeConstructorName
))
386 if (is_static
&& c
.Parameters
.IsEmpty
){
387 if (default_static_constructor
!= null) {
388 Report
.SymbolRelatedToPreviousError (default_static_constructor
);
389 Report
.Error (111, c
.Location
,
390 "A member `{0}' is already defined. Rename this member or use different parameter types",
391 c
.GetSignatureForError ());
395 default_static_constructor
= c
;
397 if (c
.Parameters
.IsEmpty
)
398 default_constructor
= c
;
400 if (instance_constructors
== null)
401 instance_constructors
= new List
<MemberCore
> ();
403 instance_constructors
.Add (c
);
407 public bool AddField (FieldBase field
)
409 if (!AddMember (field
))
413 fields
= new List
<MemberCore
> ();
417 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0)
420 if (first_nonstatic_field
== null) {
421 first_nonstatic_field
= field
;
425 if (Kind
== MemberKind
.Struct
&& first_nonstatic_field
.Parent
!= field
.Parent
) {
426 Report
.SymbolRelatedToPreviousError (first_nonstatic_field
.Parent
);
427 Report
.Warning (282, 3, field
.Location
,
428 "struct instance field `{0}' found in different declaration from instance field `{1}'",
429 field
.GetSignatureForError (), first_nonstatic_field
.GetSignatureForError ());
434 public void AddProperty (Property prop
)
436 if (!AddMember (prop
) ||
437 !AddMember (prop
.Get
) || !AddMember (prop
.Set
))
440 if (properties
== null)
441 properties
= new List
<MemberCore
> ();
443 if (prop
.MemberName
.Left
!= null)
444 AddMemberToList (prop
, properties
, true);
446 AddMemberToList (prop
, properties
, false);
449 public void AddEvent (Event e
)
454 if (e
is EventProperty
) {
455 if (!AddMember (e
.Add
))
458 if (!AddMember (e
.Remove
))
463 events
= new List
<MemberCore
> ();
469 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
471 public void AddIndexer (Indexer i
)
473 if (indexers
== null)
474 indexers
= new List
<MemberCore
> ();
476 if (i
.IsExplicitImpl
)
477 AddMemberToList (i
, indexers
, true);
479 AddMemberToList (i
, indexers
, false);
482 public void AddOperator (Operator op
)
487 if (operators
== null)
488 operators
= new List
<MemberCore
> ();
493 public void AddCompilerGeneratedClass (CompilerGeneratedClass c
)
495 Report
.Debug (64, "ADD COMPILER GENERATED CLASS", this, c
);
497 if (compiler_generated
== null)
498 compiler_generated
= new List
<CompilerGeneratedClass
> ();
500 compiler_generated
.Add (c
);
503 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
505 if (a
.Type
== pa
.DefaultMember
) {
506 if (Indexers
!= null) {
507 Report
.Error (646, a
.Location
, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
512 base.ApplyAttributeBuilder (a
, cb
, pa
);
515 public override AttributeTargets AttributeTargets
{
517 throw new NotSupportedException ();
521 public IList
<TypeContainer
> Types
{
527 public IList
<MemberCore
> Methods
{
533 public IList
<MemberCore
> Constants
{
539 protected virtual Type BaseType
{
541 return TypeBuilder
.BaseType
;
545 public IList
<MemberCore
> Fields
{
551 public IList
<MemberCore
> InstanceConstructors
{
553 return instance_constructors
;
557 public IList
<MemberCore
> Properties
{
563 public IList
<MemberCore
> Events
{
569 public IList
<MemberCore
> Indexers
{
575 public IList
<MemberCore
> Operators
{
581 public IList
<TypeContainer
> Delegates
{
587 public IList
<CompilerGeneratedClass
> CompilerGeneratedClasses
{
589 return compiler_generated
;
593 protected override TypeAttributes TypeAttr
{
595 return ModifiersExtensions
.TypeAttr (ModFlags
, IsTopLevel
) | base.TypeAttr
;
599 public string IndexerName
{
601 return indexers
== null ? DefaultIndexerName
: indexer_name
;
605 public bool IsComImport
{
607 if (OptAttributes
== null)
610 return OptAttributes
.Contains (PredefinedAttributes
.Get
.ComImport
);
614 public virtual void RegisterFieldForInitialization (MemberCore field
, FieldInitializer expression
)
616 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0){
617 if (initialized_static_fields
== null) {
618 PartialContainer
.HasStaticFieldInitializer
= true;
619 initialized_static_fields
= new List
<FieldInitializer
> (4);
622 initialized_static_fields
.Add (expression
);
624 if (initialized_fields
== null)
625 initialized_fields
= new List
<FieldInitializer
> (4);
627 initialized_fields
.Add (expression
);
631 public void ResolveFieldInitializers (BlockContext ec
)
633 if (partial_parts
!= null) {
634 foreach (TypeContainer part
in partial_parts
) {
635 part
.DoResolveFieldInitializers (ec
);
638 DoResolveFieldInitializers (ec
);
641 void DoResolveFieldInitializers (BlockContext ec
)
644 if (initialized_static_fields
== null)
647 bool has_complex_initializer
= !RootContext
.Optimize
;
649 ExpressionStatement
[] init
= new ExpressionStatement
[initialized_static_fields
.Count
];
650 for (i
= 0; i
< initialized_static_fields
.Count
; ++i
) {
651 FieldInitializer fi
= initialized_static_fields
[i
];
652 ExpressionStatement s
= fi
.ResolveStatement (ec
);
654 s
= EmptyExpressionStatement
.Instance
;
655 } else if (fi
.IsComplexInitializer
) {
656 has_complex_initializer
|= true;
662 for (i
= 0; i
< initialized_static_fields
.Count
; ++i
) {
663 FieldInitializer fi
= initialized_static_fields
[i
];
665 // Need special check to not optimize code like this
666 // static int a = b = 5;
669 if (!has_complex_initializer
&& fi
.IsDefaultInitializer
)
672 ec
.CurrentBlock
.AddScopeStatement (new StatementExpression (init
[i
]));
678 if (initialized_fields
== null)
681 for (int i
= 0; i
< initialized_fields
.Count
; ++i
) {
682 FieldInitializer fi
= (FieldInitializer
) initialized_fields
[i
];
683 ExpressionStatement s
= fi
.ResolveStatement (ec
);
688 // Field is re-initialized to its default value => removed
690 if (fi
.IsDefaultInitializer
&& RootContext
.Optimize
)
693 ec
.CurrentBlock
.AddScopeStatement (new StatementExpression (s
));
697 public override string DocComment
{
709 public PendingImplementation PendingImplementations
{
710 get { return pending; }
713 public override bool GetClsCompliantAttributeValue ()
715 if (PartialContainer
!= this)
716 return PartialContainer
.GetClsCompliantAttributeValue ();
718 return base.GetClsCompliantAttributeValue ();
721 public virtual void AddBasesForPart (DeclSpace part
, List
<FullNamedExpression
> bases
)
723 // FIXME: get rid of partial_parts and store lists of bases of each part here
724 // assumed, not verified: 'part' is in 'partial_parts'
725 ((TypeContainer
) part
).type_bases
= bases
;
729 /// This function computes the Base class and also the
730 /// list of interfaces that the class or struct @c implements.
732 /// The return value is an array (might be null) of
733 /// interfaces implemented (as Types).
735 /// The @base_class argument is set to the base object or null
736 /// if this is `System.Object'.
738 protected virtual TypeExpr
[] ResolveBaseTypes (out TypeExpr base_class
)
741 if (type_bases
== null)
744 int count
= type_bases
.Count
;
745 TypeExpr
[] ifaces
= null;
746 IMemberContext base_context
= new BaseContext (this);
747 for (int i
= 0, j
= 0; i
< count
; i
++){
748 FullNamedExpression fne
= (FullNamedExpression
) type_bases
[i
];
751 // Standard ResolveAsTypeTerminal cannot be used in this case because
752 // it does ObsoleteAttribute and constraint checks which require
753 // base type to be set
755 TypeExpr fne_resolved
= fne
.ResolveAsBaseTerminal (base_context
, false);
756 if (fne_resolved
== null)
759 if (i
== 0 && Kind
== MemberKind
.Class
&& !fne_resolved
.Type
.IsInterface
) {
760 if (fne_resolved
is DynamicTypeExpr
)
761 Report
.Error (1965, Location
, "Class `{0}' cannot derive from the dynamic type",
762 GetSignatureForError ());
764 base_class
= fne_resolved
;
769 ifaces
= new TypeExpr
[count
- i
];
771 if (fne_resolved
.Type
.IsInterface
) {
772 for (int ii
= 0; ii
< j
; ++ii
) {
773 if (TypeManager
.IsEqual (fne_resolved
.Type
, ifaces
[ii
].Type
)) {
774 Report
.Error (528, Location
, "`{0}' is already listed in interface list",
775 fne_resolved
.GetSignatureForError ());
780 if (Kind
== MemberKind
.Interface
&& !IsAccessibleAs (fne_resolved
.Type
)) {
781 Report
.Error (61, fne
.Location
,
782 "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'",
783 fne_resolved
.GetSignatureForError (), GetSignatureForError ());
786 Report
.SymbolRelatedToPreviousError (fne_resolved
.Type
);
787 if (Kind
!= MemberKind
.Class
) {
788 Report
.Error (527, fne
.Location
, "Type `{0}' in interface list is not an interface", fne_resolved
.GetSignatureForError ());
789 } else if (base_class
!= null)
790 Report
.Error (1721, fne
.Location
, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
791 GetSignatureForError (), base_class
.GetSignatureForError (), fne_resolved
.GetSignatureForError ());
793 Report
.Error (1722, fne
.Location
, "`{0}': Base class `{1}' must be specified as first",
794 GetSignatureForError (), fne_resolved
.GetSignatureForError ());
798 ifaces
[j
++] = fne_resolved
;
804 TypeExpr
[] GetNormalPartialBases (ref TypeExpr base_class
)
806 var ifaces
= new List
<TypeExpr
> (0);
807 if (iface_exprs
!= null)
808 ifaces
.AddRange (iface_exprs
);
810 foreach (TypeContainer part
in partial_parts
) {
811 TypeExpr new_base_class
;
812 TypeExpr
[] new_ifaces
= part
.ResolveBaseTypes (out new_base_class
);
813 if (new_base_class
!= TypeManager
.system_object_expr
) {
814 if (base_class
== TypeManager
.system_object_expr
)
815 base_class
= new_base_class
;
817 if (new_base_class
!= null && !TypeManager
.IsEqual (new_base_class
.Type
, base_class
.Type
)) {
818 Report
.SymbolRelatedToPreviousError (base_class
.Location
, "");
819 Report
.Error (263, part
.Location
,
820 "Partial declarations of `{0}' must not specify different base classes",
821 part
.GetSignatureForError ());
828 if (new_ifaces
== null)
831 foreach (TypeExpr iface
in new_ifaces
) {
832 if (ifaces
.Contains (iface
))
839 if (ifaces
.Count
== 0)
842 return ifaces
.ToArray ();
846 // Checks that some operators come in pairs:
852 // They are matched based on the return type and the argument types
854 void CheckPairedOperators ()
856 bool has_equality_or_inequality
= false;
857 var operators
= this.operators
.ToArray ();
858 bool[] has_pair
= new bool[operators
.Length
];
860 for (int i
= 0; i
< operators
.Length
; ++i
) {
861 if (operators
[i
] == null)
864 Operator o_a
= (Operator
) operators
[i
];
865 Operator
.OpType o_type
= o_a
.OperatorType
;
866 if (o_type
== Operator
.OpType
.Equality
|| o_type
== Operator
.OpType
.Inequality
)
867 has_equality_or_inequality
= true;
869 Operator
.OpType matching_type
= o_a
.GetMatchingOperator ();
870 if (matching_type
== Operator
.OpType
.TOP
) {
875 for (int ii
= 0; ii
< operators
.Length
; ++ii
) {
876 Operator o_b
= (Operator
) operators
[ii
];
877 if (o_b
== null || o_b
.OperatorType
!= matching_type
)
880 if (!TypeManager
.IsEqual (o_a
.ReturnType
, o_b
.ReturnType
))
883 if (!TypeManager
.IsEqual (o_a
.ParameterTypes
, o_b
.ParameterTypes
))
889 // Used to ignore duplicate user conversions
895 for (int i
= 0; i
< operators
.Length
; ++i
) {
896 if (operators
[i
] == null || has_pair
[i
])
899 Operator o
= (Operator
) operators
[i
];
900 Report
.Error (216, o
.Location
,
901 "The operator `{0}' requires a matching operator `{1}' to also be defined",
902 o
.GetSignatureForError (), Operator
.GetName (o
.GetMatchingOperator ()));
905 if (has_equality_or_inequality
) {
906 if (Methods
== null || !HasEquals
)
907 Report
.Warning (660, 2, Location
, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)",
908 GetSignatureForError ());
910 if (Methods
== null || !HasGetHashCode
)
911 Report
.Warning (661, 2, Location
, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()",
912 GetSignatureForError ());
916 bool CheckGenericInterfaces (Type
[] ifaces
)
918 var already_checked
= new List
<Type
> ();
920 for (int i
= 0; i
< ifaces
.Length
; i
++) {
921 Type iface
= ifaces
[i
];
922 foreach (Type t
in already_checked
) {
926 Type
[] inferred
= new Type
[CountTypeParameters
];
927 if (!TypeManager
.MayBecomeEqualGenericInstances (iface
, t
, inferred
, null))
930 Report
.Error (695, Location
,
931 "`{0}' cannot implement both `{1}' and `{2}' " +
932 "because they may unify for some type parameter substitutions",
933 TypeManager
.CSharpName (TypeBuilder
), TypeManager
.CSharpName (iface
),
934 TypeManager
.CSharpName (t
));
938 already_checked
.Add (iface
);
946 bool CreateTypeBuilder ()
949 Type default_parent
= null;
950 if (Kind
== MemberKind
.Struct
)
951 default_parent
= TypeManager
.value_type
;
952 else if (Kind
== MemberKind
.Enum
)
953 default_parent
= TypeManager
.enum_type
;
954 else if (Kind
== MemberKind
.Delegate
)
955 default_parent
= TypeManager
.multicast_delegate_type
;
958 // Sets .size to 1 for structs with no instance fields
960 int type_size
= Kind
== MemberKind
.Struct
&& first_nonstatic_field
== null ? 1 : 0;
963 if (GlobalRootNamespace
.Instance
.IsNamespace (Name
)) {
964 Report
.Error (519, Location
, "`{0}' clashes with a predefined namespace", Name
);
968 ModuleBuilder builder
= Module
.Compiled
.Builder
;
969 TypeBuilder
= builder
.DefineType (
970 Name
, TypeAttr
, default_parent
, type_size
);
972 TypeBuilder builder
= Parent
.TypeBuilder
;
974 TypeBuilder
= builder
.DefineNestedType (
975 Basename
, TypeAttr
, default_parent
, type_size
);
977 } catch (ArgumentException
) {
978 Report
.RuntimeMissingSupport (Location
, "static classes");
982 TypeManager
.AddUserType (this);
985 string[] param_names
= new string [TypeParameters
.Length
];
986 for (int i
= 0; i
< TypeParameters
.Length
; i
++)
987 param_names
[i
] = TypeParameters
[i
].Name
;
989 GenericTypeParameterBuilder
[] gen_params
= TypeBuilder
.DefineGenericParameters (param_names
);
991 int offset
= CountTypeParameters
;
992 if (CurrentTypeParameters
!= null)
993 offset
-= CurrentTypeParameters
.Length
;
996 nested_gen_params
= new GenericTypeParameterBuilder
[offset
];
997 Array
.Copy (gen_params
, nested_gen_params
, offset
);
1000 for (int i
= offset
; i
< gen_params
.Length
; i
++)
1001 CurrentTypeParameters
[i
- offset
].Define (gen_params
[i
]);
1007 bool DefineBaseTypes ()
1009 iface_exprs
= ResolveBaseTypes (out base_type
);
1010 if (partial_parts
!= null) {
1011 iface_exprs
= GetNormalPartialBases (ref base_type
);
1015 // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1016 // which in turn should have called DefineType()s on base types if necessary.
1018 // None of the code below should trigger DefineType()s on classes that we depend on.
1019 // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1021 // Let's do it as soon as possible, since code below can call DefineType() on classes
1022 // that depend on us to be populated before they are.
1024 if (!(this is CompilerGeneratedClass
) && !(this is Delegate
))
1025 RootContext
.RegisterOrder (this);
1027 if (!CheckRecursiveDefinition (this))
1030 if (base_type
!= null && base_type
.Type
!= null) {
1031 TypeBuilder
.SetParent (base_type
.Type
);
1034 // add interfaces that were not added at type creation
1035 if (iface_exprs
!= null) {
1036 ifaces
= TypeManager
.ExpandInterfaces (iface_exprs
);
1040 foreach (Type itype
in ifaces
)
1041 TypeBuilder
.AddInterfaceImplementation (itype
);
1043 if (!CheckGenericInterfaces (ifaces
))
1046 TypeManager
.RegisterBuilder (TypeBuilder
, ifaces
);
1053 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1055 public TypeBuilder
CreateType ()
1057 if (TypeBuilder
!= null)
1063 if (!CreateTypeBuilder ()) {
1068 if (partial_parts
!= null) {
1069 foreach (TypeContainer part
in partial_parts
)
1070 part
.TypeBuilder
= TypeBuilder
;
1073 if (Types
!= null) {
1074 foreach (TypeContainer tc
in Types
) {
1075 if (tc
.CreateType () == null) {
1087 public override TypeBuilder
DefineType ()
1094 type_defined
= true;
1096 if (CreateType () == null) {
1101 if (!DefineBaseTypes ()) {
1106 if (!DefineNestedTypes ()) {
1114 public override void SetParameterInfo (List
<Constraints
> constraints_list
)
1116 base.SetParameterInfo (constraints_list
);
1118 if (!is_generic
|| PartialContainer
== this)
1121 TypeParameter
[] tc_names
= PartialContainer
.TypeParameters
;
1122 for (int i
= 0; i
< tc_names
.Length
; ++i
) {
1123 if (tc_names
[i
].Name
!= type_params
[i
].Name
) {
1124 Report
.SymbolRelatedToPreviousError (PartialContainer
.Location
, "");
1125 Report
.Error (264, Location
, "Partial declarations of `{0}' must have the same type parameter names in the same order",
1126 GetSignatureForError ());
1130 if (tc_names
[i
].Variance
!= type_params
[i
].Variance
) {
1131 Report
.SymbolRelatedToPreviousError (PartialContainer
.Location
, "");
1132 Report
.Error (1067, Location
, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
1133 GetSignatureForError ());
1139 void UpdateTypeParameterConstraints (TypeContainer part
)
1141 TypeParameter
[] current_params
= type_params
;
1142 for (int i
= 0; i
< current_params
.Length
; i
++) {
1143 Constraints c
= part
.type_params
[i
].Constraints
;
1147 if (current_params
[i
].UpdateConstraints (part
, c
))
1150 Report
.SymbolRelatedToPreviousError (Location
, "");
1151 Report
.Error (265, part
.Location
,
1152 "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
1153 GetSignatureForError (), current_params
[i
].GetSignatureForError ());
1157 public bool ResolveType ()
1159 if (!DoResolveType ())
1162 if (compiler_generated
!= null) {
1163 foreach (CompilerGeneratedClass c
in compiler_generated
)
1164 if (!c
.ResolveType ())
1171 protected virtual bool DoResolveType ()
1176 if (PartialContainer
!= this)
1177 throw new InternalErrorException ();
1179 TypeExpr current_type
= null;
1180 if (CurrentTypeParameters
!= null) {
1181 foreach (TypeParameter type_param
in CurrentTypeParameters
) {
1182 if (!type_param
.Resolve (this)) {
1188 if (partial_parts
!= null) {
1189 foreach (TypeContainer part
in partial_parts
)
1190 UpdateTypeParameterConstraints (part
);
1194 for (int i
= 0; i
< TypeParameters
.Length
; ++i
) {
1196 // FIXME: Same should be done for delegates
1197 // TODO: Quite ugly way how to propagate constraints to
1200 if (nested_gen_params
!= null && i
< nested_gen_params
.Length
) {
1201 TypeParameters
[i
].SetConstraints (nested_gen_params
[i
]);
1203 if (!TypeParameters
[i
].DefineType (this)) {
1210 // TODO: Very strange, why not simple make generic type from
1211 // current type parameters
1212 current_type
= new GenericTypeExpr (this, Location
);
1213 current_type
= current_type
.ResolveAsTypeTerminal (this, false);
1214 if (current_type
== null) {
1219 currentType
= current_type
.Type
;
1223 protected virtual bool DefineNestedTypes ()
1225 if (Types
!= null) {
1226 foreach (TypeContainer tc
in Types
)
1227 if (tc
.DefineType () == null)
1231 if (Delegates
!= null) {
1232 foreach (Delegate d
in Delegates
)
1233 if (d
.DefineType () == null)
1240 TypeContainer InTransit
;
1242 protected bool CheckRecursiveDefinition (TypeContainer tc
)
1244 if (InTransit
!= null) {
1245 Report
.SymbolRelatedToPreviousError (this);
1246 if (this is Interface
)
1248 529, tc
.Location
, "Inherited interface `{0}' causes a " +
1249 "cycle in the interface hierarchy of `{1}'",
1250 GetSignatureForError (), tc
.GetSignatureForError ());
1253 146, tc
.Location
, "Circular base class dependency " +
1254 "involving `{0}' and `{1}'",
1255 tc
.GetSignatureForError (), GetSignatureForError ());
1261 if (base_type
!= null && base_type
.Type
!= null) {
1262 Type t
= TypeManager
.DropGenericTypeArguments (base_type
.Type
);
1263 TypeContainer ptc
= TypeManager
.LookupTypeContainer (t
);
1264 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition (this))
1268 if (iface_exprs
!= null) {
1269 foreach (TypeExpr iface
in iface_exprs
) {
1270 Type itype
= TypeManager
.DropGenericTypeArguments (iface
.Type
);
1271 TypeContainer ptc
= TypeManager
.LookupTypeContainer (itype
);
1272 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition (this))
1277 if (!IsTopLevel
&& !Parent
.PartialContainer
.CheckRecursiveDefinition (this))
1284 public override TypeParameter
[] CurrentTypeParameters
{
1286 return PartialContainer
.type_params
;
1291 /// Populates our TypeBuilder with fields and methods
1293 public sealed override bool Define ()
1295 if (members_defined
)
1296 return members_defined_ok
;
1298 members_defined_ok
= DoDefineMembers ();
1299 members_defined
= true;
1301 return members_defined_ok
;
1304 protected virtual bool DoDefineMembers ()
1306 if (iface_exprs
!= null) {
1307 foreach (TypeExpr iface
in iface_exprs
) {
1308 ObsoleteAttribute oa
= AttributeTester
.GetObsoleteAttribute (iface
.Type
);
1309 if ((oa
!= null) && !IsObsolete
)
1310 AttributeTester
.Report_ObsoleteMessage (
1311 oa
, iface
.GetSignatureForError (), Location
, Report
);
1313 GenericTypeExpr ct
= iface
as GenericTypeExpr
;
1315 // TODO: passing `this' is wrong, should be base type iface instead
1316 TypeManager
.CheckTypeVariance (ct
.Type
, Variance
.Covariant
, this);
1318 if (!ct
.CheckConstraints (this))
1321 if (ct
.HasDynamicArguments ()) {
1322 Report
.Error (1966, iface
.Location
,
1323 "`{0}': cannot implement a dynamic interface `{1}'",
1324 GetSignatureForError (), iface
.GetSignatureForError ());
1331 if (base_type
!= null) {
1332 ObsoleteAttribute obsolete_attr
= AttributeTester
.GetObsoleteAttribute (base_type
.Type
);
1333 if (obsolete_attr
!= null && !IsObsolete
)
1334 AttributeTester
.Report_ObsoleteMessage (obsolete_attr
, base_type
.GetSignatureForError (), Location
, Report
);
1336 GenericTypeExpr ct
= base_type
as GenericTypeExpr
;
1337 if ((ct
!= null) && !ct
.CheckConstraints (this))
1340 TypeContainer baseContainer
= TypeManager
.LookupTypeContainer(base_type
.Type
);
1341 if (baseContainer
!= null)
1342 baseContainer
.Define();
1344 member_cache
= new MemberCache (base_type
.Type
, this);
1345 } else if (Kind
== MemberKind
.Interface
) {
1346 member_cache
= new MemberCache (null, this);
1347 Type
[] ifaces
= TypeManager
.GetInterfaces (TypeBuilder
);
1348 for (int i
= 0; i
< ifaces
.Length
; ++i
)
1349 member_cache
.AddInterface (TypeManager
.LookupMemberCache (ifaces
[i
]));
1351 member_cache
= new MemberCache (null, this);
1355 foreach (TypeContainer tc
in types
)
1356 member_cache
.AddNestedType (tc
);
1358 if (delegates
!= null)
1359 foreach (Delegate d
in delegates
)
1360 member_cache
.AddNestedType (d
);
1362 if (partial_parts
!= null) {
1363 foreach (TypeContainer part
in partial_parts
)
1364 part
.member_cache
= member_cache
;
1368 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Basename
, false);
1369 if (conflict_symbol
== null) {
1370 if ((ModFlags
& Modifiers
.NEW
) != 0)
1371 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1373 if ((ModFlags
& Modifiers
.NEW
) == 0) {
1374 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
1375 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1376 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
1381 DefineContainerMembers (constants
);
1382 DefineContainerMembers (fields
);
1384 if (Kind
== MemberKind
.Struct
|| Kind
== MemberKind
.Class
) {
1385 pending
= PendingImplementation
.GetPendingImplementations (this);
1387 if (requires_delayed_unmanagedtype_check
) {
1388 requires_delayed_unmanagedtype_check
= false;
1389 foreach (FieldBase f
in fields
) {
1390 if (f
.MemberType
!= null && f
.MemberType
.IsPointer
)
1391 TypeManager
.VerifyUnmanaged (Compiler
, f
.MemberType
, f
.Location
);
1397 // Constructors are not in the defined_names array
1399 DefineContainerMembers (instance_constructors
);
1401 DefineContainerMembers (events
);
1402 DefineContainerMembers (ordered_explicit_member_list
);
1403 DefineContainerMembers (ordered_member_list
);
1405 if (operators
!= null) {
1406 DefineContainerMembers (operators
);
1407 CheckPairedOperators ();
1410 DefineContainerMembers (delegates
);
1412 ComputeIndexerName();
1413 CheckEqualsAndGetHashCode();
1415 if (CurrentType
!= null) {
1416 GenericType
= CurrentType
;
1420 // FIXME: This hack is needed because member cache does not work
1421 // with generic types, we rely on runtime to inflate dynamic types.
1422 // TODO: This hack requires member cache refactoring to be removed
1424 if (TypeManager
.IsGenericType (TypeBuilder
))
1425 member_cache
= new MemberCache (this);
1430 protected virtual void DefineContainerMembers (System
.Collections
.IList mcal
) // IList<MemberCore>
1433 foreach (MemberCore mc
in mcal
) {
1436 } catch (Exception e
) {
1437 throw new InternalErrorException (mc
, e
);
1443 protected virtual void ComputeIndexerName ()
1445 if (indexers
== null)
1448 string class_indexer_name
= null;
1451 // If there's both an explicit and an implicit interface implementation, the
1452 // explicit one actually implements the interface while the other one is just
1453 // a normal indexer. See bug #37714.
1456 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
1457 foreach (Indexer i
in indexers
) {
1458 if (i
.InterfaceType
!= null) {
1459 if (seen_normal_indexers
)
1460 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
1464 seen_normal_indexers
= true;
1466 if (class_indexer_name
== null) {
1467 class_indexer_name
= i
.ShortName
;
1471 if (i
.ShortName
!= class_indexer_name
)
1472 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");
1475 if (class_indexer_name
!= null)
1476 indexer_name
= class_indexer_name
;
1479 protected virtual void EmitIndexerName ()
1481 if (!seen_normal_indexers
)
1484 PredefinedAttribute pa
= PredefinedAttributes
.Get
.DefaultMember
;
1485 if (pa
.Constructor
== null &&
1486 !pa
.ResolveConstructor (Location
, TypeManager
.string_type
))
1489 CustomAttributeBuilder cb
= new CustomAttributeBuilder (pa
.Constructor
, new string [] { IndexerName }
);
1490 TypeBuilder
.SetCustomAttribute (cb
);
1493 protected virtual void CheckEqualsAndGetHashCode ()
1495 if (methods
== null)
1498 if (HasEquals
&& !HasGetHashCode
) {
1499 Report
.Warning (659, 3, this.Location
, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", this.GetSignatureForError ());
1503 public MemberInfo
FindBaseMemberWithSameName (string name
, bool ignore_methods
)
1505 return BaseCache
== null ? null : BaseCache
.FindMemberWithSameName (name
, ignore_methods
, null);
1509 /// This function is based by a delegate to the FindMembers routine
1511 static bool AlwaysAccept (MemberInfo m
, object filterCriteria
)
1517 /// This filter is used by FindMembers, and we just keep
1518 /// a global for the filter to `AlwaysAccept'
1520 static MemberFilter accepting_filter
;
1523 static TypeContainer ()
1525 accepting_filter
= new MemberFilter (AlwaysAccept
);
1528 public MethodInfo
[] GetMethods ()
1530 var members
= new List
<MethodInfo
> ();
1534 if (methods
!= null) {
1535 int len
= methods
.Count
;
1536 for (int i
= 0; i
< len
; i
++) {
1537 Method m
= (Method
) methods
[i
];
1539 members
.Add (m
.MethodBuilder
);
1543 if (operators
!= null) {
1544 int len
= operators
.Count
;
1545 for (int i
= 0; i
< len
; i
++) {
1546 Operator o
= (Operator
) operators
[i
];
1548 members
.Add (o
.MethodBuilder
);
1552 if (properties
!= null) {
1553 int len
= properties
.Count
;
1554 for (int i
= 0; i
< len
; i
++) {
1555 Property p
= (Property
) properties
[i
];
1557 if (p
.GetBuilder
!= null)
1558 members
.Add (p
.GetBuilder
);
1559 if (p
.SetBuilder
!= null)
1560 members
.Add (p
.SetBuilder
);
1564 if (indexers
!= null) {
1565 int len
= indexers
.Count
;
1566 for (int i
= 0; i
< len
; i
++) {
1567 Indexer ix
= (Indexer
) indexers
[i
];
1569 if (ix
.GetBuilder
!= null)
1570 members
.Add (ix
.GetBuilder
);
1571 if (ix
.SetBuilder
!= null)
1572 members
.Add (ix
.SetBuilder
);
1576 if (events
!= null) {
1577 int len
= events
.Count
;
1578 for (int i
= 0; i
< len
; i
++) {
1579 Event e
= (Event
) events
[i
];
1581 if (e
.AddBuilder
!= null)
1582 members
.Add (e
.AddBuilder
);
1583 if (e
.RemoveBuilder
!= null)
1584 members
.Add (e
.RemoveBuilder
);
1588 return members
.ToArray ();
1591 // Indicated whether container has StructLayout attribute set Explicit
1592 public bool HasExplicitLayout
{
1593 get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
1594 set { caching_flags |= Flags.HasExplicitLayout; }
1597 public bool HasStructLayout
{
1598 get { return (caching_flags & Flags.HasStructLayout) != 0; }
1599 set { caching_flags |= Flags.HasStructLayout; }
1603 // Return the nested type with name @name. Ensures that the nested type
1604 // is defined if necessary. Do _not_ use this when you have a MemberCache handy.
1606 public Type
FindNestedType (string name
)
1608 if (PartialContainer
!= this)
1609 throw new InternalErrorException ("should not happen");
1611 var lists
= new[] { types, delegates }
;
1613 for (int j
= 0; j
< lists
.Length
; ++j
) {
1614 var list
= lists
[j
];
1618 int len
= list
.Count
;
1619 for (int i
= 0; i
< len
; ++i
) {
1621 if (ds
.Basename
== name
) {
1622 return ds
.DefineType ();
1630 private void FindMembers_NestedTypes (Modifiers modflags
,
1631 BindingFlags bf
, MemberFilter filter
, object criteria
,
1632 ref List
<MemberInfo
> members
)
1634 var lists
= new[] { types, delegates }
;
1636 for (int j
= 0; j
< lists
.Length
; ++j
) {
1637 var list
= lists
[j
];
1641 int len
= list
.Count
;
1642 for (int i
= 0; i
< len
; i
++) {
1645 if ((ds
.ModFlags
& modflags
) == 0)
1648 TypeBuilder tb
= ds
.TypeBuilder
;
1650 if (!(criteria
is string) || ds
.Basename
.Equals (criteria
))
1651 tb
= ds
.DefineType ();
1654 if (tb
!= null && (filter (tb
, criteria
) == true)) {
1655 if (members
== null)
1656 members
= new List
<MemberInfo
> ();
1665 /// This method returns the members of this type just like Type.FindMembers would
1666 /// Only, we need to use this for types which are _being_ defined because MS'
1667 /// implementation can't take care of that.
1670 // FIXME: return an empty static array instead of null, that cleans up
1671 // some code and is consistent with some coding conventions I just found
1675 // Notice that in various cases we check if our field is non-null,
1676 // something that would normally mean that there was a bug elsewhere.
1678 // The problem happens while we are defining p-invoke methods, as those
1679 // will trigger a FindMembers, but this happens before things are defined
1681 // Since the whole process is a no-op, it is fine to check for null here.
1683 // TODO: This approach will be one day completely removed, it's already
1684 // used at few places only
1687 public override MemberList
FindMembers (MemberTypes mt
, BindingFlags bf
,
1688 MemberFilter filter
, object criteria
)
1690 List
<MemberInfo
> members
= null;
1692 Modifiers modflags
= 0;
1693 if ((bf
& BindingFlags
.Public
) != 0)
1694 modflags
|= Modifiers
.PUBLIC
| Modifiers
.PROTECTED
|
1696 if ((bf
& BindingFlags
.NonPublic
) != 0)
1697 modflags
|= Modifiers
.PRIVATE
;
1699 Modifiers static_mask
= 0, static_flags
= 0;
1700 switch (bf
& (BindingFlags
.Static
| BindingFlags
.Instance
)) {
1701 case BindingFlags
.Static
:
1702 static_mask
= static_flags
= Modifiers
.STATIC
;
1705 case BindingFlags
.Instance
:
1706 static_mask
= Modifiers
.STATIC
;
1711 static_mask
= static_flags
= 0;
1715 Timer
.StartTimer (TimerType
.TcFindMembers
);
1718 filter
= accepting_filter
;
1720 if ((mt
& MemberTypes
.Field
) != 0) {
1721 if (fields
!= null) {
1722 int len
= fields
.Count
;
1723 for (int i
= 0; i
< len
; i
++) {
1724 FieldBase f
= (FieldBase
) fields
[i
];
1726 if ((f
.ModFlags
& modflags
) == 0)
1728 if ((f
.ModFlags
& static_mask
) != static_flags
)
1731 FieldBuilder fb
= f
.FieldBuilder
;
1732 if (fb
!= null && filter (fb
, criteria
) == true) {
1733 if (members
== null)
1734 members
= new List
<MemberInfo
> ();
1741 if (constants
!= null) {
1742 int len
= constants
.Count
;
1743 for (int i
= 0; i
< len
; i
++) {
1744 Const con
= (Const
) constants
[i
];
1746 if ((con
.ModFlags
& modflags
) == 0)
1748 if ((con
.ModFlags
& static_mask
) != static_flags
)
1751 FieldBuilder fb
= con
.FieldBuilder
;
1753 // Define parent and not member, otherwise membercache can be null
1754 if (con
.Parent
.Define ())
1755 fb
= con
.FieldBuilder
;
1757 if (fb
!= null && filter (fb
, criteria
) == true) {
1758 if (members
== null)
1759 members
= new List
<MemberInfo
> ();
1767 if ((mt
& MemberTypes
.Method
) != 0) {
1768 if (methods
!= null) {
1769 int len
= methods
.Count
;
1770 for (int i
= 0; i
< len
; i
++) {
1771 MethodOrOperator m
= (MethodOrOperator
) methods
[i
];
1773 if ((m
.ModFlags
& modflags
) == 0)
1775 if ((m
.ModFlags
& static_mask
) != static_flags
)
1778 MethodBuilder mb
= m
.MethodBuilder
;
1780 if (mb
!= null && filter (mb
, criteria
) == true) {
1781 if (members
== null)
1782 members
= new List
<MemberInfo
> ();
1789 if (operators
!= null) {
1790 int len
= operators
.Count
;
1791 for (int i
= 0; i
< len
; i
++) {
1792 Operator o
= (Operator
) operators
[i
];
1794 if ((o
.ModFlags
& modflags
) == 0)
1796 if ((o
.ModFlags
& static_mask
) != static_flags
)
1799 MethodBuilder ob
= o
.MethodBuilder
;
1800 if (ob
!= null && filter (ob
, criteria
) == true) {
1801 if (members
== null)
1802 members
= new List
<MemberInfo
> ();
1809 if (events
!= null) {
1810 foreach (Event e
in events
) {
1811 if ((e
.ModFlags
& modflags
) == 0)
1813 if ((e
.ModFlags
& static_mask
) != static_flags
)
1816 MethodBuilder b
= e
.AddBuilder
;
1817 if (b
!= null && filter (b
, criteria
)) {
1818 if (members
== null)
1819 members
= new List
<MemberInfo
> ();
1824 b
= e
.RemoveBuilder
;
1825 if (b
!= null && filter (b
, criteria
)) {
1826 if (members
== null)
1827 members
= new List
<MemberInfo
> ();
1834 if (properties
!= null) {
1835 int len
= properties
.Count
;
1836 for (int i
= 0; i
< len
; i
++) {
1837 Property p
= (Property
) properties
[i
];
1839 if ((p
.ModFlags
& modflags
) == 0)
1841 if ((p
.ModFlags
& static_mask
) != static_flags
)
1847 if (b
!= null && filter (b
, criteria
) == true) {
1848 if (members
== null)
1849 members
= new List
<MemberInfo
> ();
1855 if (b
!= null && filter (b
, criteria
) == true) {
1856 if (members
== null)
1857 members
= new List
<MemberInfo
> ();
1864 if (indexers
!= null) {
1865 int len
= indexers
.Count
;
1866 for (int i
= 0; i
< len
; i
++) {
1867 Indexer ix
= (Indexer
) indexers
[i
];
1869 if ((ix
.ModFlags
& modflags
) == 0)
1871 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1877 if (b
!= null && filter (b
, criteria
) == true) {
1878 if (members
== null)
1879 members
= new List
<MemberInfo
> ();
1885 if (b
!= null && filter (b
, criteria
) == true) {
1886 if (members
== null)
1887 members
= new List
<MemberInfo
> ();
1895 if ((mt
& MemberTypes
.Event
) != 0) {
1896 if (events
!= null) {
1897 int len
= events
.Count
;
1898 for (int i
= 0; i
< len
; i
++) {
1899 Event e
= (Event
) events
[i
];
1901 if ((e
.ModFlags
& modflags
) == 0)
1903 if ((e
.ModFlags
& static_mask
) != static_flags
)
1906 MemberInfo eb
= e
.EventBuilder
;
1907 if (eb
!= null && filter (eb
, criteria
) == true) {
1908 if (members
== null)
1909 members
= new List
<MemberInfo
> ();
1911 members
.Add (e
.EventBuilder
);
1917 if ((mt
& MemberTypes
.Property
) != 0){
1918 if (properties
!= null) {
1919 int len
= properties
.Count
;
1920 for (int i
= 0; i
< len
; i
++) {
1921 Property p
= (Property
) properties
[i
];
1923 if ((p
.ModFlags
& modflags
) == 0)
1925 if ((p
.ModFlags
& static_mask
) != static_flags
)
1928 MemberInfo pb
= p
.PropertyBuilder
;
1929 if (pb
!= null && filter (pb
, criteria
) == true) {
1930 if (members
== null)
1931 members
= new List
<MemberInfo
> ();
1933 members
.Add (p
.PropertyBuilder
);
1938 if (indexers
!= null) {
1939 int len
= indexers
.Count
;
1940 for (int i
= 0; i
< len
; i
++) {
1941 Indexer ix
= (Indexer
) indexers
[i
];
1943 if ((ix
.ModFlags
& modflags
) == 0)
1945 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1948 MemberInfo ib
= ix
.PropertyBuilder
;
1949 if (ib
!= null && filter (ib
, criteria
) == true) {
1950 if (members
== null)
1951 members
= new List
<MemberInfo
> ();
1953 members
.Add (ix
.PropertyBuilder
);
1959 if ((mt
& MemberTypes
.NestedType
) != 0)
1960 FindMembers_NestedTypes (modflags
, bf
, filter
, criteria
, ref members
);
1962 if ((mt
& MemberTypes
.Constructor
) != 0){
1963 if (((bf
& BindingFlags
.Instance
) != 0) && (instance_constructors
!= null)){
1964 int len
= instance_constructors
.Count
;
1965 for (int i
= 0; i
< len
; i
++) {
1966 Constructor c
= (Constructor
) instance_constructors
[i
];
1968 ConstructorBuilder cb
= c
.ConstructorBuilder
;
1969 if (cb
!= null && filter (cb
, criteria
) == true) {
1970 if (members
== null)
1971 members
= new List
<MemberInfo
> ();
1978 if (((bf
& BindingFlags
.Static
) != 0) && (default_static_constructor
!= null)){
1979 ConstructorBuilder cb
=
1980 default_static_constructor
.ConstructorBuilder
;
1982 if (cb
!= null && filter (cb
, criteria
) == true) {
1983 if (members
== null)
1984 members
= new List
<MemberInfo
> ();
1992 // Lookup members in base if requested.
1994 if ((bf
& BindingFlags
.DeclaredOnly
) == 0) {
1995 if (TypeBuilder
.BaseType
!= null) {
1996 MemberList list
= FindMembers (TypeBuilder
.BaseType
, mt
, bf
, filter
, criteria
);
1997 if (list
.Count
> 0) {
1998 if (members
== null)
1999 members
= new List
<MemberInfo
> ();
2001 members
.AddRange (list
);
2006 Timer
.StopTimer (TimerType
.TcFindMembers
);
2008 if (members
== null)
2009 return MemberList
.Empty
;
2011 return new MemberList (members
);
2014 public override MemberCache MemberCache
{
2016 return member_cache
;
2020 public static MemberList
FindMembers (Type t
, MemberTypes mt
, BindingFlags bf
,
2021 MemberFilter filter
, object criteria
)
2023 DeclSpace ds
= TypeManager
.LookupDeclSpace (t
);
2026 return ds
.FindMembers (mt
, bf
, filter
, criteria
);
2028 return new MemberList (t
.FindMembers (mt
, bf
, filter
, criteria
));
2032 /// Emits the values for the constants
2034 public void EmitConstants ()
2036 if (constants
!= null)
2037 foreach (Const con
in constants
)
2042 void CheckMemberUsage (List
<MemberCore
> al
, string member_type
)
2047 foreach (MemberCore mc
in al
) {
2048 if ((mc
.ModFlags
& Modifiers
.AccessibilityMask
) != Modifiers
.PRIVATE
)
2051 if (!mc
.IsUsed
&& (mc
.caching_flags
& Flags
.Excluded
) == 0) {
2052 Report
.Warning (169, 3, mc
.Location
, "The private {0} `{1}' is never used", member_type
, mc
.GetSignatureForError ());
2057 public virtual void VerifyMembers ()
2060 // Check for internal or private fields that were never assigned
2062 if (Report
.WarningLevel
>= 3) {
2063 if (RootContext
.EnhancedWarnings
) {
2064 CheckMemberUsage (properties
, "property");
2065 CheckMemberUsage (methods
, "method");
2066 CheckMemberUsage (constants
, "constant");
2069 if (fields
!= null){
2070 bool is_type_exposed
= Kind
== MemberKind
.Struct
|| IsExposedFromAssembly ();
2071 foreach (FieldBase f
in fields
) {
2072 if ((f
.ModFlags
& Modifiers
.AccessibilityMask
) != Modifiers
.PRIVATE
) {
2073 if (is_type_exposed
)
2080 if ((f
.caching_flags
& Flags
.IsAssigned
) == 0)
2081 Report
.Warning (169, 3, f
.Location
, "The private field `{0}' is never used", f
.GetSignatureForError ());
2083 Report
.Warning (414, 3, f
.Location
, "The private field `{0}' is assigned but its value is never used",
2084 f
.GetSignatureForError ());
2090 // Only report 649 on level 4
2092 if (Report
.WarningLevel
< 4)
2095 if ((f
.caching_flags
& Flags
.IsAssigned
) != 0)
2099 // Don't be pendatic over serializable attributes
2101 if (f
.OptAttributes
!= null || PartialContainer
.HasStructLayout
)
2104 Constant c
= New
.Constantify (f
.MemberType
);
2105 Report
.Warning (649, 4, f
.Location
, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2106 f
.GetSignatureForError (), c
== null ? "null" : c
.AsString ());
2112 // TODO: move to ClassOrStruct
2113 void EmitConstructors ()
2115 if (instance_constructors
== null)
2118 if (TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
) && RootContext
.VerifyClsCompliance
&& IsClsComplianceRequired ()) {
2119 bool has_compliant_args
= false;
2121 foreach (Constructor c
in instance_constructors
) {
2125 catch (Exception e
) {
2126 throw new InternalErrorException (c
, e
);
2129 if (has_compliant_args
)
2132 has_compliant_args
= c
.HasCompliantArgs
;
2134 if (!has_compliant_args
)
2135 Report
.Warning (3015, 1, Location
, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2137 foreach (Constructor c
in instance_constructors
) {
2141 catch (Exception e
) {
2142 throw new InternalErrorException (c
, e
);
2149 /// Emits the code, this step is performed after all
2150 /// the types, enumerations, constructors
2152 public virtual void EmitType ()
2154 if (OptAttributes
!= null)
2155 OptAttributes
.Emit ();
2159 EmitConstructors ();
2161 // Can not continue if constants are broken
2163 if (Report
.Errors
> 0)
2166 if (default_static_constructor
!= null)
2167 default_static_constructor
.Emit ();
2169 if (operators
!= null)
2170 foreach (Operator o
in operators
)
2173 if (properties
!= null)
2174 foreach (Property p
in properties
)
2177 if (indexers
!= null) {
2178 foreach (Indexer indx
in indexers
)
2183 if (events
!= null){
2184 foreach (Event e
in Events
)
2188 if (methods
!= null) {
2189 for (int i
= 0; i
< methods
.Count
; ++i
)
2190 ((MethodOrOperator
) methods
[i
]).Emit ();
2194 foreach (FieldBase f
in fields
)
2197 if (delegates
!= null) {
2198 foreach (Delegate d
in Delegates
) {
2203 if (pending
!= null)
2204 pending
.VerifyPendingMethods (Report
);
2206 if (Report
.Errors
> 0)
2209 if (compiler_generated
!= null) {
2210 for (int i
= 0; i
< compiler_generated
.Count
; ++i
)
2211 ((CompilerGeneratedClass
) compiler_generated
[i
]).EmitType ();
2215 public override void CloseType ()
2217 if ((caching_flags
& Flags
.CloseTypeCreated
) != 0)
2221 caching_flags
|= Flags
.CloseTypeCreated
;
2222 TypeBuilder
.CreateType ();
2223 } catch (TypeLoadException
){
2225 // This is fine, the code still created the type
2227 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2228 // Console.WriteLine (e.Message);
2229 } catch (Exception e
) {
2230 throw new InternalErrorException (this, e
);
2234 foreach (TypeContainer tc
in Types
)
2235 if (tc
.Kind
== MemberKind
.Struct
)
2238 foreach (TypeContainer tc
in Types
)
2239 if (tc
.Kind
!= MemberKind
.Struct
)
2243 if (Delegates
!= null)
2244 foreach (Delegate d
in Delegates
)
2247 if (compiler_generated
!= null)
2248 foreach (CompilerGeneratedClass c
in compiler_generated
)
2251 PartialContainer
= null;
2253 // properties = null;
2256 initialized_fields
= null;
2257 initialized_static_fields
= null;
2259 ordered_explicit_member_list
= null;
2260 ordered_member_list
= null;
2265 compiler_generated
= null;
2266 default_constructor
= null;
2267 default_static_constructor
= null;
2269 OptAttributes
= null;
2272 member_cache
= null;
2276 // Performs the validation on a Method's modifiers (properties have
2277 // the same properties).
2279 public bool MethodModifiersValid (MemberCore mc
)
2281 const Modifiers vao
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
);
2282 const Modifiers va
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
);
2283 const Modifiers nv
= (Modifiers
.NEW
| Modifiers
.VIRTUAL
);
2285 var flags
= mc
.ModFlags
;
2288 // At most one of static, virtual or override
2290 if ((flags
& Modifiers
.STATIC
) != 0){
2291 if ((flags
& vao
) != 0){
2292 Report
.Error (112, mc
.Location
, "A static member `{0}' cannot be marked as override, virtual or abstract",
2293 mc
.GetSignatureForError ());
2298 if (Kind
== MemberKind
.Struct
){
2299 if ((flags
& va
) != 0){
2300 ModifiersExtensions
.Error_InvalidModifier (mc
.Location
, "virtual or abstract", Report
);
2305 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& nv
) != 0){
2306 Report
.Error (113, mc
.Location
, "A member `{0}' marked as override cannot be marked as new or virtual",
2307 mc
.GetSignatureForError ());
2312 // If the declaration includes the abstract modifier, then the
2313 // declaration does not include static, virtual or extern
2315 if ((flags
& Modifiers
.ABSTRACT
) != 0){
2316 if ((flags
& Modifiers
.EXTERN
) != 0){
2318 180, mc
.Location
, "`{0}' cannot be both extern and abstract", mc
.GetSignatureForError ());
2322 if ((flags
& Modifiers
.SEALED
) != 0) {
2323 Report
.Error (502, mc
.Location
, "`{0}' cannot be both abstract and sealed", mc
.GetSignatureForError ());
2327 if ((flags
& Modifiers
.VIRTUAL
) != 0){
2328 Report
.Error (503, mc
.Location
, "The abstract method `{0}' cannot be marked virtual", mc
.GetSignatureForError ());
2332 if ((ModFlags
& Modifiers
.ABSTRACT
) == 0){
2333 Report
.SymbolRelatedToPreviousError (this);
2334 Report
.Error (513, mc
.Location
, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2335 mc
.GetSignatureForError (), GetSignatureForError ());
2340 if ((flags
& Modifiers
.PRIVATE
) != 0){
2341 if ((flags
& vao
) != 0){
2342 Report
.Error (621, mc
.Location
, "`{0}': virtual or abstract members cannot be private", mc
.GetSignatureForError ());
2347 if ((flags
& Modifiers
.SEALED
) != 0){
2348 if ((flags
& Modifiers
.OVERRIDE
) == 0){
2349 Report
.Error (238, mc
.Location
, "`{0}' cannot be sealed because it is not an override", mc
.GetSignatureForError ());
2357 public Constructor DefaultStaticConstructor
{
2358 get { return default_static_constructor; }
2361 protected override bool VerifyClsCompliance ()
2363 if (!base.VerifyClsCompliance ())
2368 Type base_type
= TypeBuilder
.BaseType
;
2369 if (base_type
!= null && !AttributeTester
.IsClsCompliant (base_type
)) {
2370 Report
.Warning (3009, 1, Location
, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager
.CSharpName (base_type
));
2377 /// Checks whether container name is CLS Compliant
2379 void VerifyClsName ()
2381 Dictionary
<string, object> base_members
= base_cache
== null ?
2382 new Dictionary
<string, object> () :
2383 base_cache
.GetPublicMembers ();
2384 var this_members
= new Dictionary
<string, object> ();
2386 foreach (var entry
in defined_names
) {
2387 MemberCore mc
= entry
.Value
;
2388 if (!mc
.IsClsComplianceRequired ())
2391 string name
= entry
.Key
;
2392 string basename
= name
.Substring (name
.LastIndexOf ('.') + 1);
2394 string lcase
= basename
.ToLower (System
.Globalization
.CultureInfo
.InvariantCulture
);
2396 if (!base_members
.TryGetValue (lcase
, out found
)) {
2397 if (!this_members
.TryGetValue (lcase
, out found
)) {
2398 this_members
.Add (lcase
, mc
);
2403 if ((mc
.ModFlags
& Modifiers
.OVERRIDE
) != 0)
2406 if (found
is MemberInfo
) {
2407 if (basename
== ((MemberInfo
) found
).Name
)
2409 Report
.SymbolRelatedToPreviousError ((MemberInfo
) found
);
2411 Report
.SymbolRelatedToPreviousError ((MemberCore
) found
);
2414 Report
.Warning (3005, 1, mc
.Location
, "Identifier `{0}' differing only in case is not CLS-compliant", mc
.GetSignatureForError ());
2420 /// Performs checks for an explicit interface implementation. First it
2421 /// checks whether the `interface_type' is a base inteface implementation.
2422 /// Then it checks whether `name' exists in the interface type.
2424 public bool VerifyImplements (InterfaceMemberBase mb
)
2426 if (ifaces
!= null) {
2427 foreach (Type t
in ifaces
){
2428 if (TypeManager
.IsEqual (t
, mb
.InterfaceType
))
2433 Report
.SymbolRelatedToPreviousError (mb
.InterfaceType
);
2434 Report
.Error (540, mb
.Location
, "`{0}': containing type does not implement interface `{1}'",
2435 mb
.GetSignatureForError (), TypeManager
.CSharpName (mb
.InterfaceType
));
2439 public override Type
LookupAnyGeneric (string typeName
)
2441 if (types
!= null) {
2442 foreach (TypeContainer tc
in types
) {
2446 int pos
= tc
.Basename
.LastIndexOf ('`');
2447 if (pos
== typeName
.Length
&& String
.Compare (typeName
, 0, tc
.Basename
, 0, pos
) == 0)
2448 return tc
.TypeBuilder
;
2452 return base.LookupAnyGeneric (typeName
);
2455 public void Mark_HasEquals ()
2457 cached_method
|= CachedMethods
.Equals
;
2460 public void Mark_HasGetHashCode ()
2462 cached_method
|= CachedMethods
.GetHashCode
;
2466 /// Method container contains Equals method
2468 public bool HasEquals
{
2470 return (cached_method
& CachedMethods
.Equals
) != 0;
2475 /// Method container contains GetHashCode method
2477 public bool HasGetHashCode
{
2479 return (cached_method
& CachedMethods
.GetHashCode
) != 0;
2483 public bool HasStaticFieldInitializer
{
2485 return (cached_method
& CachedMethods
.HasStaticFieldInitializer
) != 0;
2489 cached_method
|= CachedMethods
.HasStaticFieldInitializer
;
2491 cached_method
&= ~CachedMethods
.HasStaticFieldInitializer
;
2499 string IMemberContainer
.Name
{
2505 Type IMemberContainer
.Type
{
2511 bool IMemberContainer
.IsInterface
{
2513 return Kind
== MemberKind
.Interface
;
2517 MemberList IMemberContainer
.GetMembers (MemberTypes mt
, BindingFlags bf
)
2519 BindingFlags new_bf
= bf
| BindingFlags
.DeclaredOnly
;
2521 if (GenericType
!= null)
2522 return TypeManager
.FindMembers (GenericType
, mt
, new_bf
,
2525 return FindMembers (mt
, new_bf
, null, null);
2529 // Generates xml doc comments (if any), and if required,
2530 // handle warning report.
2532 internal override void GenerateDocComment (DeclSpace ds
)
2534 DocUtil
.GenerateTypeDocComment (this, ds
, Report
);
2537 public override string DocCommentHeader
{
2538 get { return "T:"; }
2541 public MemberCache BaseCache
{
2543 if (base_cache
!= null)
2545 if (TypeBuilder
.BaseType
!= null)
2546 base_cache
= TypeManager
.LookupMemberCache (TypeBuilder
.BaseType
);
2547 if (TypeBuilder
.IsInterface
)
2548 base_cache
= TypeManager
.LookupBaseInterfacesCache (TypeBuilder
);
2554 public abstract class ClassOrStruct
: TypeContainer
2556 Dictionary
<SecurityAction
, PermissionSet
> declarative_security
;
2558 public ClassOrStruct (NamespaceEntry ns
, DeclSpace parent
,
2559 MemberName name
, Attributes attrs
, MemberKind kind
)
2560 : base (ns
, parent
, name
, attrs
, kind
)
2564 protected override bool AddToContainer (MemberCore symbol
, string name
)
2566 if (name
== MemberName
.Name
) {
2567 if (symbol
is TypeParameter
) {
2568 Report
.Error (694, symbol
.Location
,
2569 "Type parameter `{0}' has same name as containing type, or method",
2570 symbol
.GetSignatureForError ());
2574 InterfaceMemberBase imb
= symbol
as InterfaceMemberBase
;
2575 if (imb
== null || !imb
.IsExplicitImpl
) {
2576 Report
.SymbolRelatedToPreviousError (this);
2577 Report
.Error (542, symbol
.Location
, "`{0}': member names cannot be the same as their enclosing type",
2578 symbol
.GetSignatureForError ());
2583 return base.AddToContainer (symbol
, name
);
2586 public override void VerifyMembers ()
2588 base.VerifyMembers ();
2590 if ((events
!= null) && Report
.WarningLevel
>= 3) {
2591 foreach (Event e
in events
){
2592 // Note: The event can be assigned from same class only, so we can report
2593 // this warning for all accessibility modes
2594 if ((e
.caching_flags
& Flags
.IsUsed
) == 0)
2595 Report
.Warning (67, 3, e
.Location
, "The event `{0}' is never used", e
.GetSignatureForError ());
2600 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
2602 if (a
.IsValidSecurityAttribute ()) {
2603 if (declarative_security
== null)
2604 declarative_security
= new Dictionary
<SecurityAction
, PermissionSet
> ();
2606 a
.ExtractSecurityPermissionSet (declarative_security
);
2610 if (a
.Type
== pa
.StructLayout
) {
2611 PartialContainer
.HasStructLayout
= true;
2613 if (a
.GetLayoutKindValue () == LayoutKind
.Explicit
)
2614 PartialContainer
.HasExplicitLayout
= true;
2617 if (a
.Type
== pa
.Dynamic
) {
2618 a
.Error_MisusedDynamicAttribute ();
2622 base.ApplyAttributeBuilder (a
, cb
, pa
);
2626 /// Defines the default constructors
2628 protected void DefineDefaultConstructor (bool is_static
)
2630 // The default instance constructor is public
2631 // If the class is abstract, the default constructor is protected
2632 // The default static constructor is private
2636 mods
= Modifiers
.STATIC
| Modifiers
.PRIVATE
;
2638 mods
= ((ModFlags
& Modifiers
.ABSTRACT
) != 0) ? Modifiers
.PROTECTED
: Modifiers
.PUBLIC
;
2641 Constructor c
= new Constructor (this, MemberName
.Name
, mods
,
2642 null, ParametersCompiled
.EmptyReadOnlyParameters
,
2643 new GeneratedBaseInitializer (Location
),
2647 c
.Block
= new ToplevelBlock (Compiler
, ParametersCompiled
.EmptyReadOnlyParameters
, Location
);
2650 protected override bool DoDefineMembers ()
2652 CheckProtectedModifier ();
2654 base.DoDefineMembers ();
2656 if (default_static_constructor
!= null)
2657 default_static_constructor
.Define ();
2662 public override void Emit ()
2664 if (default_static_constructor
== null && PartialContainer
.HasStaticFieldInitializer
) {
2665 DefineDefaultConstructor (true);
2666 default_static_constructor
.Define ();
2671 if (declarative_security
!= null) {
2672 foreach (var de
in declarative_security
) {
2673 TypeBuilder
.AddDeclarativeSecurity (de
.Key
, de
.Value
);
2678 public override ExtensionMethodGroupExpr
LookupExtensionMethod (Type extensionType
, string name
, Location loc
)
2680 DeclSpace top_level
= Parent
;
2681 if (top_level
!= null) {
2682 while (top_level
.Parent
!= null)
2683 top_level
= top_level
.Parent
;
2685 var candidates
= NamespaceEntry
.NS
.LookupExtensionMethod (extensionType
, this, name
);
2686 if (candidates
!= null)
2687 return new ExtensionMethodGroupExpr (candidates
, NamespaceEntry
, extensionType
, loc
);
2690 return NamespaceEntry
.LookupExtensionMethod (extensionType
, name
, loc
);
2693 protected override TypeAttributes TypeAttr
{
2695 if (default_static_constructor
== null)
2696 return base.TypeAttr
| TypeAttributes
.BeforeFieldInit
;
2698 return base.TypeAttr
;
2704 // TODO: should be sealed
2705 public class Class
: ClassOrStruct
{
2706 const Modifiers AllowedModifiers
=
2709 Modifiers
.PROTECTED
|
2710 Modifiers
.INTERNAL
|
2712 Modifiers
.ABSTRACT
|
2717 public const TypeAttributes StaticClassAttribute
= TypeAttributes
.Abstract
| TypeAttributes
.Sealed
;
2719 public Class (NamespaceEntry ns
, DeclSpace parent
, MemberName name
, Modifiers mod
,
2721 : base (ns
, parent
, name
, attrs
, MemberKind
.Class
)
2723 var accmods
= Parent
.Parent
== null ? Modifiers
.INTERNAL
: Modifiers
.PRIVATE
;
2724 this.ModFlags
= ModifiersExtensions
.Check (AllowedModifiers
, mod
, accmods
, Location
, Report
);
2726 if (IsStatic
&& RootContext
.Version
== LanguageVersion
.ISO_1
) {
2727 Report
.FeatureIsNotAvailable (Location
, "static classes");
2731 public override void AddBasesForPart (DeclSpace part
, List
<FullNamedExpression
> bases
)
2733 if (part
.Name
== "System.Object")
2734 Report
.Error (537, part
.Location
,
2735 "The class System.Object cannot have a base class or implement an interface.");
2736 base.AddBasesForPart (part
, bases
);
2739 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
2741 if (a
.Type
== pa
.AttributeUsage
) {
2742 if (!TypeManager
.IsAttributeType (BaseType
) &&
2743 TypeBuilder
.FullName
!= "System.Attribute") {
2744 Report
.Error (641, a
.Location
, "Attribute `{0}' is only valid on classes derived from System.Attribute", a
.GetSignatureForError ());
2748 if (a
.Type
== pa
.Conditional
&& !TypeManager
.IsAttributeType (BaseType
)) {
2749 Report
.Error (1689, a
.Location
, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2753 if (a
.Type
== pa
.ComImport
&& !attributes
.Contains (pa
.Guid
)) {
2754 a
.Error_MissingGuidAttribute ();
2758 if (a
.Type
== pa
.Extension
) {
2759 a
.Error_MisusedExtensionAttribute ();
2763 if (AttributeTester
.IsAttributeExcluded (a
.Type
, Location
))
2766 base.ApplyAttributeBuilder (a
, cb
, pa
);
2769 public override AttributeTargets AttributeTargets
{
2771 return AttributeTargets
.Class
;
2775 protected override void DefineContainerMembers (System
.Collections
.IList list
)
2781 base.DefineContainerMembers (list
);
2785 foreach (MemberCore m
in list
) {
2786 if (m
is Operator
) {
2787 Report
.Error (715, m
.Location
, "`{0}': Static classes cannot contain user-defined operators", m
.GetSignatureForError ());
2791 if (m
is Destructor
) {
2792 Report
.Error (711, m
.Location
, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2797 Report
.Error (720, m
.Location
, "`{0}': cannot declare indexers in a static class", m
.GetSignatureForError ());
2801 if ((m
.ModFlags
& Modifiers
.STATIC
) != 0 || m
is Enum
|| m
is Delegate
)
2804 if (m
is Constructor
) {
2805 Report
.Error (710, m
.Location
, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2809 Method method
= m
as Method
;
2810 if (method
!= null && method
.Parameters
.HasExtensionMethodType
) {
2811 Report
.Error (1105, m
.Location
, "`{0}': Extension methods must be declared static", m
.GetSignatureForError ());
2815 Report
.Error (708, m
.Location
, "`{0}': cannot declare instance members in a static class", m
.GetSignatureForError ());
2818 base.DefineContainerMembers (list
);
2821 protected override bool DoDefineMembers ()
2823 if ((ModFlags
& Modifiers
.ABSTRACT
) == Modifiers
.ABSTRACT
&& (ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) != 0) {
2824 Report
.Error (418, Location
, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2827 if ((ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) == (Modifiers
.SEALED
| Modifiers
.STATIC
)) {
2828 Report
.Error (441, Location
, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2831 if (InstanceConstructors
== null && !IsStatic
)
2832 DefineDefaultConstructor (false);
2834 return base.DoDefineMembers ();
2837 public override void Emit ()
2841 if ((ModFlags
& Modifiers
.METHOD_EXTENSION
) != 0)
2842 PredefinedAttributes
.Get
.Extension
.EmitAttribute (TypeBuilder
);
2845 protected override TypeExpr
[] ResolveBaseTypes (out TypeExpr base_class
)
2847 TypeExpr
[] ifaces
= base.ResolveBaseTypes (out base_class
);
2849 if (base_class
== null) {
2850 if (RootContext
.StdLib
)
2851 base_class
= TypeManager
.system_object_expr
;
2852 else if (Name
!= "System.Object")
2853 base_class
= TypeManager
.system_object_expr
;
2855 if (Kind
== MemberKind
.Class
&& TypeManager
.IsGenericParameter (base_class
.Type
)){
2857 689, base_class
.Location
,
2858 "Cannot derive from `{0}' because it is a type parameter",
2859 base_class
.GetSignatureForError ());
2863 if (IsGeneric
&& TypeManager
.IsAttributeType (base_class
.Type
)) {
2864 Report
.Error (698, base_class
.Location
,
2865 "A generic type cannot derive from `{0}' because it is an attribute class",
2866 base_class
.GetSignatureForError ());
2869 if (base_class
.IsSealed
){
2870 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
2871 if (base_class
.Type
.IsAbstract
) {
2872 Report
.Error (709, Location
, "`{0}': Cannot derive from static class `{1}'",
2873 GetSignatureForError (), TypeManager
.CSharpName (base_class
.Type
));
2875 Report
.Error (509, Location
, "`{0}': cannot derive from sealed type `{1}'",
2876 GetSignatureForError (), TypeManager
.CSharpName (base_class
.Type
));
2881 if (!base_class
.CanInheritFrom ()){
2882 Report
.Error (644, Location
, "`{0}' cannot derive from special class `{1}'",
2883 GetSignatureForError (), base_class
.GetSignatureForError ());
2887 if (!IsAccessibleAs (base_class
.Type
)) {
2888 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
2889 Report
.Error (60, Location
, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
2890 TypeManager
.CSharpName (base_class
.Type
), GetSignatureForError ());
2894 if (PartialContainer
.IsStaticClass
) {
2895 if (base_class
.Type
!= TypeManager
.object_type
) {
2896 Report
.Error (713, Location
, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2897 GetSignatureForError (), base_class
.GetSignatureForError ());
2901 if (ifaces
!= null) {
2902 foreach (TypeExpr t
in ifaces
)
2903 Report
.SymbolRelatedToPreviousError (t
.Type
);
2904 Report
.Error (714, Location
, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2911 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2912 /// Valid only for attribute classes.
2913 public bool IsExcluded ()
2915 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
2916 return (caching_flags
& Flags
.Excluded
) != 0;
2918 caching_flags
&= ~Flags
.Excluded_Undetected
;
2920 if (OptAttributes
== null)
2923 Attribute
[] attrs
= OptAttributes
.SearchMulti (PredefinedAttributes
.Get
.Conditional
);
2927 foreach (Attribute a
in attrs
) {
2928 string condition
= a
.GetConditionalAttributeValue ();
2929 if (Location
.CompilationUnit
.IsConditionalDefined (condition
))
2933 caching_flags
|= Flags
.Excluded
;
2938 // FIXME: How do we deal with the user specifying a different
2941 protected override TypeAttributes TypeAttr
{
2943 TypeAttributes ta
= base.TypeAttr
| TypeAttributes
.AutoLayout
| TypeAttributes
.Class
;
2945 ta
|= StaticClassAttribute
;
2951 public sealed class Struct
: ClassOrStruct
{
2953 bool is_unmanaged
, has_unmanaged_check_done
;
2956 // Modifiers allowed in a struct declaration
2958 const Modifiers AllowedModifiers
=
2961 Modifiers
.PROTECTED
|
2962 Modifiers
.INTERNAL
|
2966 public Struct (NamespaceEntry ns
, DeclSpace parent
, MemberName name
,
2967 Modifiers mod
, Attributes attrs
)
2968 : base (ns
, parent
, name
, attrs
, MemberKind
.Struct
)
2970 var accmods
= parent
.Parent
== null ? Modifiers
.INTERNAL
: Modifiers
.PRIVATE
;
2972 this.ModFlags
= ModifiersExtensions
.Check (AllowedModifiers
, mod
, accmods
, Location
, Report
);
2974 this.ModFlags
|= Modifiers
.SEALED
;
2977 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
2979 base.ApplyAttributeBuilder (a
, cb
, pa
);
2982 // When struct constains fixed fixed and struct layout has explicitly
2983 // set CharSet, its value has to be propagated to compiler generated
2984 // fixed field types
2986 if (a
.Type
== pa
.StructLayout
&& Fields
!= null && a
.HasField ("CharSet")) {
2987 for (int i
= 0; i
< Fields
.Count
; ++i
) {
2988 FixedField ff
= Fields
[i
] as FixedField
;
2990 ff
.SetCharSet (TypeBuilder
.Attributes
);
2995 public override AttributeTargets AttributeTargets
{
2997 return AttributeTargets
.Struct
;
3001 public override bool IsUnmanagedType ()
3006 if (requires_delayed_unmanagedtype_check
)
3009 if (has_unmanaged_check_done
)
3010 return is_unmanaged
;
3012 has_unmanaged_check_done
= true;
3014 foreach (FieldBase f
in fields
) {
3015 if ((f
.ModFlags
& Modifiers
.STATIC
) != 0)
3018 // It can happen when recursive unmanaged types are defined
3019 // struct S { S* s; }
3020 Type mt
= f
.MemberType
;
3022 has_unmanaged_check_done
= false;
3023 requires_delayed_unmanagedtype_check
= true;
3027 // TODO: Remove when pointer types are under mcs control
3028 while (mt
.IsPointer
)
3029 mt
= TypeManager
.GetElementType (mt
);
3030 if (TypeManager
.IsEqual (mt
, TypeBuilder
))
3033 if (TypeManager
.IsUnmanagedType (mt
))
3039 is_unmanaged
= true;
3043 protected override TypeExpr
[] ResolveBaseTypes (out TypeExpr base_class
)
3045 TypeExpr
[] ifaces
= base.ResolveBaseTypes (out base_class
);
3047 // If we are compiling our runtime,
3048 // and we are defining ValueType, then our
3049 // base is `System.Object'.
3051 if (base_class
== null) {
3052 if (!RootContext
.StdLib
&& Name
== "System.ValueType")
3053 base_class
= TypeManager
.system_object_expr
;
3055 base_class
= TypeManager
.system_valuetype_expr
;
3062 // FIXME: Allow the user to specify a different set of attributes
3063 // in some cases (Sealed for example is mandatory for a class,
3064 // but what SequentialLayout can be changed
3066 protected override TypeAttributes TypeAttr
{
3068 const TypeAttributes DefaultTypeAttributes
=
3069 TypeAttributes
.SequentialLayout
|
3070 TypeAttributes
.Sealed
;
3072 return base.TypeAttr
| DefaultTypeAttributes
;
3076 public override void RegisterFieldForInitialization (MemberCore field
, FieldInitializer expression
)
3078 if ((field
.ModFlags
& Modifiers
.STATIC
) == 0) {
3079 Report
.Error (573, field
.Location
, "`{0}': Structs cannot have instance field initializers",
3080 field
.GetSignatureForError ());
3083 base.RegisterFieldForInitialization (field
, expression
);
3091 public sealed class Interface
: TypeContainer
, IMemberContainer
{
3094 /// Modifiers allowed in a class declaration
3096 public const Modifiers AllowedModifiers
=
3099 Modifiers
.PROTECTED
|
3100 Modifiers
.INTERNAL
|
3104 public Interface (NamespaceEntry ns
, DeclSpace parent
, MemberName name
, Modifiers mod
,
3106 : base (ns
, parent
, name
, attrs
, MemberKind
.Interface
)
3108 var accmods
= parent
.Parent
== null ? Modifiers
.INTERNAL
: Modifiers
.PRIVATE
;
3110 this.ModFlags
= ModifiersExtensions
.Check (AllowedModifiers
, mod
, accmods
, name
.Location
, Report
);
3113 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
3115 if (a
.Type
== pa
.ComImport
&& !attributes
.Contains (pa
.Guid
)) {
3116 a
.Error_MissingGuidAttribute ();
3120 base.ApplyAttributeBuilder (a
, cb
, pa
);
3124 public override AttributeTargets AttributeTargets
{
3126 return AttributeTargets
.Interface
;
3130 protected override TypeAttributes TypeAttr
{
3132 const TypeAttributes DefaultTypeAttributes
=
3133 TypeAttributes
.AutoLayout
|
3134 TypeAttributes
.Abstract
|
3135 TypeAttributes
.Interface
;
3137 return base.TypeAttr
| DefaultTypeAttributes
;
3141 protected override bool VerifyClsCompliance ()
3143 if (!base.VerifyClsCompliance ())
3146 if (ifaces
!= null) {
3147 foreach (Type t
in ifaces
) {
3148 if (AttributeTester
.IsClsCompliant (t
))
3151 Report
.SymbolRelatedToPreviousError (t
);
3152 Report
.Warning (3027, 1, Location
, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3153 GetSignatureForError (), TypeManager
.CSharpName (t
));
3161 public abstract class InterfaceMemberBase
: MemberBase
{
3163 // Whether this is an interface member.
3165 public bool IsInterface
;
3168 // If true, this is an explicit interface implementation
3170 public bool IsExplicitImpl
;
3172 protected bool is_external_implementation
;
3175 // The interface type we are explicitly implementing
3177 public Type InterfaceType
;
3180 // The method we're overriding if this is an override method.
3182 protected MethodInfo base_method
;
3184 readonly Modifiers explicit_mod_flags
;
3185 public MethodAttributes flags
;
3187 public InterfaceMemberBase (DeclSpace parent
, GenericMethod generic
,
3188 FullNamedExpression type
, Modifiers mod
, Modifiers allowed_mod
,
3189 MemberName name
, Attributes attrs
)
3190 : base (parent
, generic
, type
, mod
, allowed_mod
, Modifiers
.PRIVATE
,
3193 IsInterface
= parent
.PartialContainer
.Kind
== MemberKind
.Interface
;
3194 IsExplicitImpl
= (MemberName
.Left
!= null);
3195 explicit_mod_flags
= mod
;
3198 protected override bool CheckBase ()
3200 if (!base.CheckBase ())
3203 if ((caching_flags
& Flags
.MethodOverloadsExist
) != 0)
3204 CheckForDuplications ();
3206 if (IsExplicitImpl
|| this is Destructor
)
3209 // Is null for System.Object while compiling corlib and base interfaces
3210 if (Parent
.PartialContainer
.BaseCache
== null) {
3211 if ((ModFlags
& Modifiers
.NEW
) != 0) {
3212 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3217 Type base_ret_type
= null;
3218 base_method
= FindOutBaseMethod (ref base_ret_type
);
3220 // method is override
3221 if (base_method
!= null) {
3222 if (!CheckMethodAgainstBase (base_ret_type
))
3225 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3226 ObsoleteAttribute oa
= AttributeTester
.GetMethodObsoleteAttribute (base_method
);
3228 if (OptAttributes
== null || !OptAttributes
.Contains (PredefinedAttributes
.Get
.Obsolete
)) {
3229 Report
.SymbolRelatedToPreviousError (base_method
);
3230 Report
.Warning (672, 1, Location
, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3231 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3234 if (OptAttributes
!= null && OptAttributes
.Contains (PredefinedAttributes
.Get
.Obsolete
)) {
3235 Report
.SymbolRelatedToPreviousError (base_method
);
3236 Report
.Warning (809, 1, Location
, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3237 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3244 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Name
, !((this is Event
) || (this is Property
)));
3245 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3246 if (conflict_symbol
!= null) {
3247 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3249 Report
.Error (72, Location
, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3250 else if (this is PropertyBase
)
3251 Report
.Error (544, Location
, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3253 Report
.Error (505, Location
, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3255 Report
.Error (115, Location
, "`{0}' is marked as an override but no suitable {1} found to override",
3256 GetSignatureForError (), SimpleName
.GetMemberType (this));
3261 if (conflict_symbol
== null) {
3262 if ((ModFlags
& Modifiers
.NEW
) != 0) {
3263 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3268 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3269 if (this is MethodOrOperator
&& conflict_symbol
.MemberType
== MemberTypes
.Method
)
3272 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3273 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3274 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3280 protected virtual bool CheckForDuplications ()
3282 return Parent
.MemberCache
.CheckExistingMembersOverloads (
3283 this, GetFullName (MemberName
), ParametersCompiled
.EmptyReadOnlyParameters
, Report
);
3287 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3288 // that have been defined.
3290 // `name' is the user visible name for reporting errors (this is used to
3291 // provide the right name regarding method names and properties)
3293 bool CheckMethodAgainstBase (Type base_method_type
)
3297 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0){
3298 if (!(base_method
.IsAbstract
|| base_method
.IsVirtual
)){
3299 Report
.SymbolRelatedToPreviousError (base_method
);
3300 Report
.Error (506, Location
,
3301 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3302 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3306 // Now we check that the overriden method is not final
3308 if (base_method
.IsFinal
) {
3309 Report
.SymbolRelatedToPreviousError (base_method
);
3310 Report
.Error (239, Location
, "`{0}': cannot override inherited member `{1}' because it is sealed",
3311 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3315 // Check that the permissions are not being changed
3317 MethodAttributes thisp
= flags
& MethodAttributes
.MemberAccessMask
;
3318 MethodAttributes base_classp
= base_method
.Attributes
& MethodAttributes
.MemberAccessMask
;
3320 if (!CheckAccessModifiers (thisp
, base_classp
, base_method
)) {
3321 Error_CannotChangeAccessModifiers (Location
, base_method
, base_classp
, null);
3325 if (!TypeManager
.IsEqual (MemberType
, TypeManager
.TypeToCoreType (base_method_type
))) {
3326 Report
.SymbolRelatedToPreviousError (base_method
);
3327 if (this is PropertyBasedMember
) {
3328 Report
.Error (1715, Location
, "`{0}': type must be `{1}' to match overridden member `{2}'",
3329 GetSignatureForError (), TypeManager
.CSharpName (base_method_type
), TypeManager
.CSharpSignature (base_method
));
3332 Report
.Error (508, Location
, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3333 GetSignatureForError (), TypeManager
.CSharpName (base_method_type
), TypeManager
.CSharpSignature (base_method
));
3339 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3340 if ((ModFlags
& Modifiers
.OVERRIDE
) == 0) {
3341 ModFlags
|= Modifiers
.NEW
;
3342 Report
.SymbolRelatedToPreviousError (base_method
);
3343 if (!IsInterface
&& (base_method
.IsVirtual
|| base_method
.IsAbstract
)) {
3344 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",
3345 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3346 if (base_method
.IsAbstract
){
3347 Report
.Error (533, Location
, "`{0}' hides inherited abstract member `{1}'",
3348 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3352 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3353 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3357 if (base_method
.IsAbstract
&& !IsInterface
) {
3358 Report
.SymbolRelatedToPreviousError (base_method
);
3359 Report
.Error (533, Location
, "`{0}' hides inherited abstract member `{1}'",
3360 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3368 protected bool CheckAccessModifiers (MethodAttributes thisp
, MethodAttributes base_classp
, MethodInfo base_method
)
3370 if ((base_classp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3372 // when overriding protected internal, the method can be declared
3373 // protected internal only within the same assembly or assembly
3374 // which has InternalsVisibleTo
3376 if ((thisp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3377 return TypeManager
.IsThisOrFriendAssembly (Parent
.Module
.Assembly
, base_method
.DeclaringType
.Assembly
);
3378 } else if ((thisp
& MethodAttributes
.Family
) != MethodAttributes
.Family
) {
3380 // if it's not "protected internal", it must be "protected"
3384 } else if (Parent
.TypeBuilder
.Assembly
== base_method
.DeclaringType
.Assembly
) {
3386 // protected within the same assembly - an error
3389 } else if ((thisp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
)) !=
3390 (base_classp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
))) {
3392 // protected ok, but other attributes differ - report an error
3398 return (thisp
== base_classp
);
3402 public override bool Define ()
3405 ModFlags
= Modifiers
.PUBLIC
| Modifiers
.ABSTRACT
|
3406 Modifiers
.VIRTUAL
| (ModFlags
& (Modifiers
.UNSAFE
| Modifiers
.NEW
));
3408 flags
= MethodAttributes
.Public
|
3409 MethodAttributes
.Abstract
|
3410 MethodAttributes
.HideBySig
|
3411 MethodAttributes
.NewSlot
|
3412 MethodAttributes
.Virtual
;
3414 Parent
.PartialContainer
.MethodModifiersValid (this);
3416 flags
= ModifiersExtensions
.MethodAttr (ModFlags
);
3419 if (IsExplicitImpl
) {
3420 TypeExpr iface_texpr
= MemberName
.Left
.GetTypeExpression ().ResolveAsTypeTerminal (this, false);
3421 if (iface_texpr
== null)
3424 if ((ModFlags
& Modifiers
.PARTIAL
) != 0) {
3425 Report
.Error (754, Location
, "A partial method `{0}' cannot explicitly implement an interface",
3426 GetSignatureForError ());
3429 InterfaceType
= iface_texpr
.Type
;
3431 if (!InterfaceType
.IsInterface
) {
3432 Report
.SymbolRelatedToPreviousError (InterfaceType
);
3433 Report
.Error (538, Location
, "The type `{0}' in explicit interface declaration is not an interface",
3434 TypeManager
.CSharpName (InterfaceType
));
3436 Parent
.PartialContainer
.VerifyImplements (this);
3439 ModifiersExtensions
.Check (Modifiers
.AllowedExplicitImplFlags
, explicit_mod_flags
, 0, Location
, Report
);
3442 return base.Define ();
3445 protected bool DefineParameters (ParametersCompiled parameters
)
3447 if (!parameters
.Resolve (this))
3451 for (int i
= 0; i
< parameters
.Count
; ++i
) {
3452 Parameter p
= parameters
[i
];
3454 if (p
.HasDefaultValue
&& (IsExplicitImpl
|| this is Operator
|| (this is Indexer
&& parameters
.Count
== 1)))
3455 p
.Warning_UselessOptionalParameter (Report
);
3457 if (p
.CheckAccessibility (this))
3460 Type t
= parameters
.Types
[i
];
3461 Report
.SymbolRelatedToPreviousError (t
);
3462 if (this is Indexer
)
3463 Report
.Error (55, Location
,
3464 "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3465 TypeManager
.CSharpName (t
), GetSignatureForError ());
3466 else if (this is Operator
)
3467 Report
.Error (57, Location
,
3468 "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3469 TypeManager
.CSharpName (t
), GetSignatureForError ());
3471 Report
.Error (51, Location
,
3472 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3473 TypeManager
.CSharpName (t
), GetSignatureForError ());
3479 public override void Emit()
3481 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3482 // We are more strict than csc and report this as an error because SRE does not allow emit that
3483 if ((ModFlags
& Modifiers
.EXTERN
) != 0 && !is_external_implementation
) {
3484 if (this is Constructor
) {
3485 Report
.Error (824, Location
,
3486 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3488 Report
.Error (626, Location
,
3489 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3490 GetSignatureForError ());
3497 public override bool EnableOverloadChecks (MemberCore overload
)
3500 // Two members can differ in their explicit interface
3501 // type parameter only
3503 InterfaceMemberBase imb
= overload
as InterfaceMemberBase
;
3504 if (imb
!= null && imb
.IsExplicitImpl
) {
3505 if (IsExplicitImpl
) {
3506 caching_flags
|= Flags
.MethodOverloadsExist
;
3511 return IsExplicitImpl
;
3514 protected void Error_CannotChangeAccessModifiers (Location loc
, MemberInfo base_method
, MethodAttributes ma
, string suffix
)
3516 Report
.SymbolRelatedToPreviousError (base_method
);
3517 string base_name
= TypeManager
.GetFullNameSignature (base_method
);
3518 string this_name
= GetSignatureForError ();
3519 if (suffix
!= null) {
3520 base_name
+= suffix
;
3521 this_name
+= suffix
;
3524 Report
.Error (507, loc
, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3525 this_name
, ModifiersExtensions
.GetDescription (ma
), base_name
);
3528 protected static string Error722
{
3530 return "`{0}': static types cannot be used as return types";
3535 /// Gets base method and its return type
3537 protected abstract MethodInfo
FindOutBaseMethod (ref Type base_ret_type
);
3540 // The "short" name of this property / indexer / event. This is the
3541 // name without the explicit interface.
3543 public string ShortName
3545 get { return MemberName.Name; }
3546 set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
3550 // Returns full metadata method name
3552 public string GetFullName (MemberName name
)
3554 if (!IsExplicitImpl
)
3558 // When dealing with explicit members a full interface type
3559 // name is added to member name to avoid possible name conflicts
3561 // We use CSharpName which gets us full name with benefit of
3562 // replacing predefined names which saves some space and name
3565 return TypeManager
.CSharpName (InterfaceType
) + "." + name
.Name
;
3568 protected override bool VerifyClsCompliance ()
3570 if (!base.VerifyClsCompliance ()) {
3571 if (IsInterface
&& HasClsCompliantAttribute
&& Parent
.IsClsComplianceRequired ()) {
3572 Report
.Warning (3010, 1, Location
, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
3575 if ((ModFlags
& Modifiers
.ABSTRACT
) != 0 && Parent
.TypeBuilder
.IsClass
&& IsExposedFromAssembly () && Parent
.IsClsComplianceRequired ()) {
3576 Report
.Warning (3011, 1, Location
, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3581 if (GenericMethod
!= null)
3582 GenericMethod
.VerifyClsCompliance ();
3587 public override bool IsUsed
3589 get { return IsExplicitImpl || base.IsUsed; }
3594 public abstract class MemberBase
: MemberCore
3596 protected FullNamedExpression type_name
;
3597 protected Type member_type
;
3599 public readonly DeclSpace ds
;
3600 public readonly GenericMethod GenericMethod
;
3602 protected MemberBase (DeclSpace parent
, GenericMethod generic
,
3603 FullNamedExpression type
, Modifiers mod
, Modifiers allowed_mod
, Modifiers def_mod
,
3604 MemberName name
, Attributes attrs
)
3605 : base (parent
, name
, attrs
)
3607 this.ds
= generic
!= null ? generic
: (DeclSpace
) parent
;
3608 this.type_name
= type
;
3609 ModFlags
= ModifiersExtensions
.Check (allowed_mod
, mod
, def_mod
, Location
, Report
);
3610 GenericMethod
= generic
;
3611 if (GenericMethod
!= null)
3612 GenericMethod
.ModFlags
= ModFlags
;
3616 // Main member define entry
3618 public override bool Define ()
3620 DoMemberTypeIndependentChecks ();
3623 // Returns false only when type resolution failed
3625 if (!ResolveMemberType ())
3628 DoMemberTypeDependentChecks ();
3633 // Any type_name independent checks
3635 protected virtual void DoMemberTypeIndependentChecks ()
3637 if ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0 &&
3638 (ModFlags
& (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
)) != 0) {
3639 Report
.Error (549, Location
, "New virtual member `{0}' is declared in a sealed class `{1}'",
3640 GetSignatureForError (), Parent
.GetSignatureForError ());
3645 // Any type_name dependent checks
3647 protected virtual void DoMemberTypeDependentChecks ()
3649 // verify accessibility
3650 if (!IsAccessibleAs (MemberType
)) {
3651 Report
.SymbolRelatedToPreviousError (MemberType
);
3652 if (this is Property
)
3653 Report
.Error (53, Location
,
3654 "Inconsistent accessibility: property type `" +
3655 TypeManager
.CSharpName (MemberType
) + "' is less " +
3656 "accessible than property `" + GetSignatureForError () + "'");
3657 else if (this is Indexer
)
3658 Report
.Error (54, Location
,
3659 "Inconsistent accessibility: indexer return type `" +
3660 TypeManager
.CSharpName (MemberType
) + "' is less " +
3661 "accessible than indexer `" + GetSignatureForError () + "'");
3662 else if (this is MethodCore
) {
3663 if (this is Operator
)
3664 Report
.Error (56, Location
,
3665 "Inconsistent accessibility: return type `" +
3666 TypeManager
.CSharpName (MemberType
) + "' is less " +
3667 "accessible than operator `" + GetSignatureForError () + "'");
3669 Report
.Error (50, Location
,
3670 "Inconsistent accessibility: return type `" +
3671 TypeManager
.CSharpName (MemberType
) + "' is less " +
3672 "accessible than method `" + GetSignatureForError () + "'");
3674 Report
.Error (52, Location
,
3675 "Inconsistent accessibility: field type `" +
3676 TypeManager
.CSharpName (MemberType
) + "' is less " +
3677 "accessible than field `" + GetSignatureForError () + "'");
3681 Variance variance
= this is Event
? Variance
.Contravariant
: Variance
.Covariant
;
3682 TypeManager
.CheckTypeVariance (MemberType
, variance
, this);
3685 protected bool IsTypePermitted ()
3687 if (TypeManager
.IsSpecialType (MemberType
)) {
3688 Report
.Error (610, Location
, "Field or property cannot be of type `{0}'", TypeManager
.CSharpName (MemberType
));
3694 protected virtual bool CheckBase ()
3696 CheckProtectedModifier ();
3701 public Type MemberType
{
3702 get { return member_type; }
3705 protected virtual bool ResolveMemberType ()
3707 if (member_type
!= null)
3708 throw new InternalErrorException ("Multi-resolve");
3710 TypeExpr te
= type_name
.ResolveAsTypeTerminal (this, false);
3715 // Replace original type name, error reporting can use fully resolved name
3719 member_type
= te
.Type
;