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@gmail.com)
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-2011 Novell, Inc
12 // Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
17 using System.Collections.Generic;
18 using System.Runtime.InteropServices;
19 using System.Security;
20 using System.Security.Permissions;
22 using System.Diagnostics;
23 using Mono.CompilerServices.SymbolWriter;
26 using XmlElement = System.Object;
30 using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
31 using IKVM.Reflection;
32 using IKVM.Reflection.Emit;
34 using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
35 using System.Reflection;
36 using System.Reflection.Emit;
42 // General types container, used as a base class for all constructs which can hold types
44 public abstract class TypeContainer : MemberCore
46 public readonly MemberKind Kind;
48 protected List<TypeContainer> containers;
50 TypeDefinition main_container;
52 protected Dictionary<string, MemberCore> defined_names;
54 protected bool is_defined;
56 public int CounterAnonymousMethods { get; set; }
57 public int CounterAnonymousContainers { get; set; }
58 public int CounterSwitchTypes { get; set; }
60 protected TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
61 : base (parent, name, attrs)
64 defined_names = new Dictionary<string, MemberCore> ();
67 public override TypeSpec CurrentType {
73 public Dictionary<string, MemberCore> DefinedNames {
79 public TypeDefinition PartialContainer {
81 return main_container;
84 main_container = value;
88 public IList<TypeContainer> Containers {
95 // Any unattached attributes during parsing get added here. Used
98 public Attributes UnattachedAttributes {
102 public void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
104 AddTypeContainerMember (c);
107 public virtual void AddPartial (TypeDefinition next_part)
110 (PartialContainer ?? this).defined_names.TryGetValue (next_part.MemberName.Basename, out mc);
112 AddPartial (next_part, mc as TypeDefinition);
115 protected void AddPartial (TypeDefinition next_part, TypeDefinition existing)
117 next_part.ModFlags |= Modifiers.PARTIAL;
119 if (existing == null) {
120 AddTypeContainer (next_part);
124 if ((existing.ModFlags & Modifiers.PARTIAL) == 0) {
125 if (existing.Kind != next_part.Kind) {
126 AddTypeContainer (next_part);
128 Report.SymbolRelatedToPreviousError (next_part);
129 Error_MissingPartialModifier (existing);
135 if (existing.Kind != next_part.Kind) {
136 Report.SymbolRelatedToPreviousError (existing);
137 Report.Error (261, next_part.Location,
138 "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
139 next_part.GetSignatureForError ());
142 if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
143 ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) == 0 &&
144 (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) == 0)) {
145 Report.SymbolRelatedToPreviousError (existing);
146 Report.Error (262, next_part.Location,
147 "Partial declarations of `{0}' have conflicting accessibility modifiers",
148 next_part.GetSignatureForError ());
151 var tc_names = existing.CurrentTypeParameters;
152 if (tc_names != null) {
153 for (int i = 0; i < tc_names.Count; ++i) {
154 var tp = next_part.MemberName.TypeParameters[i];
155 if (tc_names[i].MemberName.Name != tp.MemberName.Name) {
156 Report.SymbolRelatedToPreviousError (existing.Location, "");
157 Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
158 next_part.GetSignatureForError ());
162 if (tc_names[i].Variance != tp.Variance) {
163 Report.SymbolRelatedToPreviousError (existing.Location, "");
164 Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
165 next_part.GetSignatureForError ());
171 if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) != 0) {
172 existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFIER | Modifiers.AccessibilityMask);
173 } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) != 0) {
174 existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFIER | Modifiers.AccessibilityMask);
175 existing.ModFlags |= next_part.ModFlags;
177 existing.ModFlags |= next_part.ModFlags;
180 existing.Definition.Modifiers = existing.ModFlags;
182 if (next_part.attributes != null) {
183 if (existing.attributes == null)
184 existing.attributes = next_part.attributes;
186 existing.attributes.AddAttributes (next_part.attributes.Attrs);
189 next_part.PartialContainer = existing;
191 existing.AddPartialPart (next_part);
193 AddTypeContainerMember (next_part);
196 public virtual void AddTypeContainer (TypeContainer tc)
198 AddTypeContainerMember (tc);
200 var tparams = tc.MemberName.TypeParameters;
201 if (tparams != null && tc.PartialContainer != null) {
202 var td = (TypeDefinition) tc;
203 for (int i = 0; i < tparams.Count; ++i) {
205 if (tp.MemberName == null)
208 td.AddNameToContainer (tp, tp.Name);
213 protected virtual void AddTypeContainerMember (TypeContainer tc)
218 public virtual void CloseContainer ()
220 if (containers != null) {
221 foreach (TypeContainer tc in containers) {
222 tc.CloseContainer ();
227 public virtual void CreateMetadataName (StringBuilder sb)
229 if (Parent != null && Parent.MemberName != null)
230 Parent.CreateMetadataName (sb);
232 MemberName.CreateMetadataName (sb);
235 public virtual bool CreateContainer ()
237 if (containers != null) {
238 foreach (TypeContainer tc in containers) {
239 tc.CreateContainer ();
246 public override bool Define ()
248 if (containers != null) {
249 foreach (TypeContainer tc in containers) {
254 // Release cache used by parser only
255 if (Module.Evaluator == null) {
256 defined_names = null;
258 defined_names.Clear ();
264 public virtual void PrepareEmit ()
266 if (containers != null) {
267 foreach (var t in containers) {
270 } catch (Exception e) {
271 if (MemberName == MemberName.Null)
274 throw new InternalErrorException (t, e);
280 public virtual bool DefineContainer ()
287 DoDefineContainer ();
289 if (containers != null) {
290 foreach (TypeContainer tc in containers) {
292 tc.DefineContainer ();
293 } catch (Exception e) {
294 if (MemberName == MemberName.Null)
297 throw new InternalErrorException (tc, e);
301 if (PartialContainer != null && PartialContainer != this) {
309 public virtual void ExpandBaseInterfaces ()
311 if (containers != null) {
312 foreach (TypeContainer tc in containers) {
313 tc.ExpandBaseInterfaces ();
318 protected virtual void DefineNamespace ()
320 if (containers != null) {
321 foreach (var tc in containers) {
323 tc.DefineNamespace ();
324 } catch (Exception e) {
325 throw new InternalErrorException (tc, e);
331 protected virtual void DoDefineContainer ()
335 public virtual void EmitContainer ()
337 if (containers != null) {
338 for (int i = 0; i < containers.Count; ++i)
339 containers[i].EmitContainer ();
343 protected void Error_MissingPartialModifier (MemberCore type)
345 Report.Error (260, type.Location,
346 "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
347 type.GetSignatureForError ());
350 public override string GetSignatureForDocumentation ()
352 if (Parent != null && Parent.MemberName != null)
353 return Parent.GetSignatureForDocumentation () + "." + MemberName.GetSignatureForDocumentation ();
355 return MemberName.GetSignatureForDocumentation ();
358 public override string GetSignatureForError ()
360 if (Parent != null && Parent.MemberName != null)
361 return Parent.GetSignatureForError () + "." + MemberName.GetSignatureForError ();
363 return MemberName.GetSignatureForError ();
366 public virtual string GetSignatureForMetadata ()
368 var sb = new StringBuilder ();
369 CreateMetadataName (sb);
370 return sb.ToString ();
373 public virtual void RemoveContainer (TypeContainer cont)
375 if (containers != null)
376 containers.Remove (cont);
378 var tc = Parent == Module ? Module : this;
379 tc.defined_names.Remove (cont.MemberName.Basename);
382 public virtual void VerifyMembers ()
384 if (containers != null) {
385 foreach (TypeContainer tc in containers)
390 public override void WriteDebugSymbol (MonoSymbolFile file)
392 if (containers != null) {
393 foreach (TypeContainer tc in containers) {
394 tc.WriteDebugSymbol (file);
400 public abstract class TypeDefinition : TypeContainer, ITypeDefinition
403 // Different context is needed when resolving type container base
404 // types. Type names come from the parent scope but type parameter
405 // names from the container scope.
407 public struct BaseContext : IMemberContext
411 public BaseContext (TypeContainer tc)
416 #region IMemberContext Members
418 public CompilerContext Compiler {
419 get { return tc.Compiler; }
422 public TypeSpec CurrentType {
423 get { return tc.PartialContainer.CurrentType; }
426 public TypeParameters CurrentTypeParameters {
427 get { return tc.PartialContainer.CurrentTypeParameters; }
430 public MemberCore CurrentMemberDefinition {
434 public bool IsObsolete {
435 get { return tc.IsObsolete; }
438 public bool IsUnsafe {
439 get { return tc.IsUnsafe; }
442 public bool IsStatic {
443 get { return tc.IsStatic; }
446 public ModuleContainer Module {
447 get { return tc.Module; }
450 public string GetSignatureForError ()
452 return tc.GetSignatureForError ();
455 public ExtensionMethodCandidates LookupExtensionMethod (string name, int arity)
460 public FullNamedExpression LookupNamespaceAlias (string name)
462 return tc.Parent.LookupNamespaceAlias (name);
465 public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
468 var tp = CurrentTypeParameters;
470 TypeParameter t = tp.Find (name);
472 return new TypeParameterExpr (t, loc);
476 return tc.Parent.LookupNamespaceOrType (name, arity, mode, loc);
486 GetHashCode = 1 << 1,
487 HasStaticFieldInitializer = 1 << 2
490 readonly List<MemberCore> members;
492 // Holds a list of fields that have initializers
493 protected List<FieldInitializer> initialized_fields;
495 // Holds a list of static fields that have initializers
496 protected List<FieldInitializer> initialized_static_fields;
498 Dictionary<MethodSpec, Method> hoisted_base_call_proxies;
500 Dictionary<string, FullNamedExpression> Cache = new Dictionary<string, FullNamedExpression> ();
503 // Points to the first non-static field added to the container.
505 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
506 // and the first one's as good as any.
508 protected FieldBase first_nonstatic_field;
511 // This one is computed after we can distinguish interfaces
512 // from classes from the arraylist `type_bases'
514 protected TypeSpec base_type;
515 FullNamedExpression base_type_expr; // TODO: It's temporary variable
516 protected TypeSpec[] iface_exprs;
518 protected List<FullNamedExpression> type_bases;
520 // Partial parts for classes only
521 List<TypeDefinition> class_partial_parts;
523 TypeDefinition InTransit;
525 public TypeBuilder TypeBuilder;
526 GenericTypeParameterBuilder[] all_tp_builders;
528 // All recursive type parameters put together sharing same
529 // TypeParameter instances
531 TypeParameters all_type_parameters;
533 public const string DefaultIndexerName = "Item";
535 bool has_normal_indexers;
538 bool members_defined;
539 bool members_defined_ok;
540 protected bool has_static_constructor;
542 private CachedMethods cached_method;
544 protected TypeSpec spec;
545 TypeSpec current_type;
547 public int DynamicSitesCounter;
548 public int AnonymousMethodsCounter;
549 public int MethodGroupsCounter;
551 static readonly string[] attribute_targets = new [] { "type" };
552 static readonly string[] attribute_targets_primary = new [] { "type", "method" };
555 /// The pending methods that need to be implemented
556 // (interfaces or abstract methods)
558 PendingImplementation pending;
560 protected TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
561 : base (parent, name, attrs, kind)
563 PartialContainer = this;
564 members = new List<MemberCore> ();
569 public List<FullNamedExpression> BaseTypeExpressions {
575 public override TypeSpec CurrentType {
577 if (current_type == null) {
578 if (IsGenericOrParentIsGeneric) {
580 // Switch to inflated version as it's used by all expressions
582 var targs = CurrentTypeParameters == null ? TypeSpec.EmptyTypes : CurrentTypeParameters.Types;
583 current_type = spec.MakeGenericType (this, targs);
593 public override TypeParameters CurrentTypeParameters {
595 return PartialContainer.MemberName.TypeParameters;
599 int CurrentTypeParametersStartIndex {
601 int total = all_tp_builders.Length;
602 if (CurrentTypeParameters != null) {
603 return total - CurrentTypeParameters.Count;
609 public virtual AssemblyDefinition DeclaringAssembly {
611 return Module.DeclaringAssembly;
615 IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
617 return Module.DeclaringAssembly;
621 public TypeSpec Definition {
627 public bool HasMembersDefined {
629 return members_defined;
633 public bool HasInstanceConstructor {
635 return (caching_flags & Flags.HasInstanceConstructor) != 0;
638 caching_flags |= Flags.HasInstanceConstructor;
642 // Indicated whether container has StructLayout attribute set Explicit
643 public bool HasExplicitLayout {
644 get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
645 set { caching_flags |= Flags.HasExplicitLayout; }
648 public bool HasOperators {
650 return (caching_flags & Flags.HasUserOperators) != 0;
653 caching_flags |= Flags.HasUserOperators;
657 public bool HasStructLayout {
658 get { return (caching_flags & Flags.HasStructLayout) != 0; }
659 set { caching_flags |= Flags.HasStructLayout; }
662 public TypeSpec[] Interfaces {
668 public bool IsGenericOrParentIsGeneric {
670 return all_type_parameters != null;
674 public bool IsTopLevel {
676 return !(Parent is TypeDefinition);
680 public bool IsPartial {
682 return (ModFlags & Modifiers.PARTIAL) != 0;
686 bool ITypeDefinition.IsTypeForwarder {
692 bool ITypeDefinition.IsCyclicTypeForwarder {
699 // Returns true for secondary partial containers
703 return PartialContainer != this;
707 public MemberCache MemberCache {
709 return spec.MemberCache;
713 public List<MemberCore> Members {
719 string ITypeDefinition.Namespace {
722 while (p.Kind != MemberKind.Namespace)
725 return p.MemberName == null ? null : p.GetSignatureForError ();
729 public ParametersCompiled PrimaryConstructorParameters { get; set; }
731 public Arguments PrimaryConstructorBaseArguments { get; set; }
733 public Location PrimaryConstructorBaseArgumentsStart { get; set; }
735 public TypeParameters TypeParametersAll {
737 return all_type_parameters;
741 public override string[] ValidAttributeTargets {
743 return PrimaryConstructorParameters != null ? attribute_targets_primary : attribute_targets;
749 public override void Accept (StructuralVisitor visitor)
751 visitor.Visit (this);
754 public void AddMember (MemberCore symbol)
756 if (symbol.MemberName.ExplicitInterface != null) {
757 if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) {
758 Report.Error (541, symbol.Location,
759 "`{0}': explicit interface declaration can only be declared in a class or struct",
760 symbol.GetSignatureForError ());
764 AddNameToContainer (symbol, symbol.MemberName.Name);
765 members.Add (symbol);
768 public override void AddTypeContainer (TypeContainer tc)
770 AddNameToContainer (tc, tc.MemberName.Basename);
772 base.AddTypeContainer (tc);
775 protected override void AddTypeContainerMember (TypeContainer tc)
779 if (containers == null)
780 containers = new List<TypeContainer> ();
782 base.AddTypeContainerMember (tc);
786 // Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
788 public virtual void AddNameToContainer (MemberCore symbol, string name)
790 if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
794 if (!PartialContainer.defined_names.TryGetValue (name, out mc)) {
795 PartialContainer.defined_names.Add (name, symbol);
799 if (symbol.EnableOverloadChecks (mc))
802 InterfaceMemberBase im = mc as InterfaceMemberBase;
803 if (im != null && im.IsExplicitImpl)
806 Report.SymbolRelatedToPreviousError (mc);
807 if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
808 Error_MissingPartialModifier (symbol);
812 if (symbol is TypeParameter) {
813 Report.Error (692, symbol.Location,
814 "Duplicate type parameter `{0}'", symbol.GetSignatureForError ());
816 Report.Error (102, symbol.Location,
817 "The type `{0}' already contains a definition for `{1}'",
818 GetSignatureForError (), name);
824 public void AddConstructor (Constructor c)
826 AddConstructor (c, false);
829 public void AddConstructor (Constructor c, bool isDefault)
831 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
833 AddNameToContainer (c, is_static ? Constructor.TypeConstructorName : Constructor.ConstructorName);
835 if (is_static && c.ParameterInfo.IsEmpty) {
836 PartialContainer.has_static_constructor = true;
838 PartialContainer.HasInstanceConstructor = true;
844 public bool AddField (FieldBase field)
848 if ((field.ModFlags & Modifiers.STATIC) != 0)
851 var first_field = PartialContainer.first_nonstatic_field;
852 if (first_field == null) {
853 PartialContainer.first_nonstatic_field = field;
857 if (Kind == MemberKind.Struct && first_field.Parent != field.Parent) {
858 Report.SymbolRelatedToPreviousError (first_field.Parent);
859 Report.Warning (282, 3, field.Location,
860 "struct instance field `{0}' found in different declaration from instance field `{1}'",
861 field.GetSignatureForError (), first_field.GetSignatureForError ());
867 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
869 public void AddIndexer (Indexer i)
874 public void AddOperator (Operator op)
876 PartialContainer.HasOperators = true;
880 public void AddPartialPart (TypeDefinition part)
882 if (Kind != MemberKind.Class)
885 if (class_partial_parts == null)
886 class_partial_parts = new List<TypeDefinition> ();
888 class_partial_parts.Add (part);
891 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
893 if (a.Target == AttributeTargets.Method) {
894 foreach (var m in members) {
895 var c = m as Constructor;
899 if (c.IsPrimaryConstructor) {
900 c.ApplyAttributeBuilder (a, ctor, cdata, pa);
905 throw new InternalErrorException ();
908 if (has_normal_indexers && a.Type == pa.DefaultMember) {
909 Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
913 if (a.Type == pa.Required) {
914 Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types");
918 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
921 public override AttributeTargets AttributeTargets {
923 throw new NotSupportedException ();
927 public TypeSpec BaseType {
929 return spec.BaseType;
933 protected virtual TypeAttributes TypeAttr {
935 return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel);
939 public int TypeParametersCount {
941 return MemberName.Arity;
945 TypeParameterSpec[] ITypeDefinition.TypeParameters {
947 var ctp = PartialContainer.CurrentTypeParameters;
948 return ctp == null ? TypeParameterSpec.EmptyTypes : ctp.Types;
952 public string GetAttributeDefaultMember ()
954 return indexer_name ?? DefaultIndexerName;
957 public bool IsComImport {
959 if (OptAttributes == null)
962 return OptAttributes.Contains (Module.PredefinedAttributes.ComImport);
966 public void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
969 PartialContainer.RegisterFieldForInitialization (field, expression);
971 if ((field.ModFlags & Modifiers.STATIC) != 0){
972 if (initialized_static_fields == null) {
973 HasStaticFieldInitializer = true;
974 initialized_static_fields = new List<FieldInitializer> (4);
977 initialized_static_fields.Add (expression);
979 if (Kind == MemberKind.Struct) {
980 if (Compiler.Settings.Version != LanguageVersion.Experimental) {
981 Report.Error (573, expression.Location, "'{0}': Structs cannot have instance property or field initializers",
982 GetSignatureForError ());
986 if (initialized_fields == null)
987 initialized_fields = new List<FieldInitializer> (4);
989 initialized_fields.Add (expression);
993 public void ResolveFieldInitializers (BlockContext ec)
995 Debug.Assert (!IsPartialPart);
998 if (initialized_static_fields == null)
1001 bool has_complex_initializer = !ec.Module.Compiler.Settings.Optimize;
1003 ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count];
1004 for (i = 0; i < initialized_static_fields.Count; ++i) {
1005 FieldInitializer fi = initialized_static_fields [i];
1006 ExpressionStatement s = fi.ResolveStatement (ec);
1008 s = EmptyExpressionStatement.Instance;
1009 } else if (!fi.IsSideEffectFree) {
1010 has_complex_initializer = true;
1016 for (i = 0; i < initialized_static_fields.Count; ++i) {
1017 FieldInitializer fi = initialized_static_fields [i];
1019 // Need special check to not optimize code like this
1020 // static int a = b = 5;
1021 // static int b = 0;
1023 if (!has_complex_initializer && fi.IsDefaultInitializer)
1026 ec.AssignmentInfoOffset += fi.AssignmentOffset;
1027 ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
1033 if (initialized_fields == null)
1036 for (int i = 0; i < initialized_fields.Count; ++i) {
1037 FieldInitializer fi = initialized_fields [i];
1040 // Clone before resolving otherwise when field initializer is needed
1041 // in more than 1 constructor any resolve after the initial one would
1042 // only took the resolved expression which is problem for expressions
1043 // that generate extra expressions or code during Resolve phase
1045 var cloned = fi.Clone (new CloneContext ());
1047 ExpressionStatement s = fi.ResolveStatement (ec);
1049 initialized_fields [i] = new FieldInitializer (fi.Field, ErrorExpression.Instance, Location.Null);
1054 // Field is re-initialized to its default value => removed
1056 if (fi.IsDefaultInitializer && Kind != MemberKind.Struct && ec.Module.Compiler.Settings.Optimize)
1059 ec.AssignmentInfoOffset += fi.AssignmentOffset;
1060 ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
1061 initialized_fields [i] = (FieldInitializer) cloned;
1065 public override string DocComment {
1077 public PendingImplementation PendingImplementations {
1078 get { return pending; }
1081 internal override void GenerateDocComment (DocumentationBuilder builder)
1086 base.GenerateDocComment (builder);
1088 foreach (var member in members)
1089 member.GenerateDocComment (builder);
1092 public TypeSpec GetAttributeCoClass ()
1094 if (OptAttributes == null)
1097 Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CoClass);
1101 return a.GetCoClassAttributeValue ();
1104 public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
1107 if (OptAttributes != null) {
1108 a = OptAttributes.Search (pa);
1114 return a.GetAttributeUsageAttribute ();
1117 public virtual CompilationSourceFile GetCompilationSourceFile ()
1119 TypeContainer ns = Parent;
1121 var sf = ns as CompilationSourceFile;
1129 public override string GetSignatureForMetadata ()
1131 if (Parent is TypeDefinition) {
1132 return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (FilterNestedName (MemberName.Basename));
1135 return base.GetSignatureForMetadata ();
1138 public virtual void SetBaseTypes (List<FullNamedExpression> baseTypes)
1140 type_bases = baseTypes;
1144 /// This function computes the Base class and also the
1145 /// list of interfaces that the class or struct @c implements.
1147 /// The return value is an array (might be null) of
1148 /// interfaces implemented (as Types).
1150 /// The @base_class argument is set to the base object or null
1151 /// if this is `System.Object'.
1153 protected virtual TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
1156 if (type_bases == null)
1159 int count = type_bases.Count;
1160 TypeSpec[] ifaces = null;
1161 var base_context = new BaseContext (this);
1162 for (int i = 0, j = 0; i < count; i++){
1163 FullNamedExpression fne = type_bases [i];
1165 var fne_resolved = fne.ResolveAsType (base_context);
1166 if (fne_resolved == null)
1169 if (i == 0 && Kind == MemberKind.Class && !fne_resolved.IsInterface) {
1170 if (fne_resolved.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
1171 Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
1172 GetSignatureForError ());
1177 base_type = fne_resolved;
1183 ifaces = new TypeSpec [count - i];
1185 if (fne_resolved.IsInterface) {
1186 for (int ii = 0; ii < j; ++ii) {
1187 if (fne_resolved == ifaces [ii]) {
1188 Report.Error (528, Location, "`{0}' is already listed in interface list",
1189 fne_resolved.GetSignatureForError ());
1194 if (Kind == MemberKind.Interface && !IsAccessibleAs (fne_resolved)) {
1195 Report.Error (61, fne.Location,
1196 "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'",
1197 fne_resolved.GetSignatureForError (), GetSignatureForError ());
1200 Report.SymbolRelatedToPreviousError (fne_resolved);
1201 if (Kind != MemberKind.Class) {
1202 Report.Error (527, fne.Location, "Type `{0}' in interface list is not an interface", fne_resolved.GetSignatureForError ());
1203 } else if (base_class != null)
1204 Report.Error (1721, fne.Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1205 GetSignatureForError (), base_class.GetSignatureForError (), fne_resolved.GetSignatureForError ());
1207 Report.Error (1722, fne.Location, "`{0}': Base class `{1}' must be specified as first",
1208 GetSignatureForError (), fne_resolved.GetSignatureForError ());
1212 ifaces [j++] = fne_resolved;
1219 // Checks that some operators come in pairs:
1225 // They are matched based on the return type and the argument types
1227 void CheckPairedOperators ()
1229 bool has_equality_or_inequality = false;
1230 List<Operator.OpType> found_matched = new List<Operator.OpType> ();
1232 for (int i = 0; i < members.Count; ++i) {
1233 var o_a = members[i] as Operator;
1237 var o_type = o_a.OperatorType;
1238 if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
1239 has_equality_or_inequality = true;
1241 if (found_matched.Contains (o_type))
1244 var matching_type = o_a.GetMatchingOperator ();
1245 if (matching_type == Operator.OpType.TOP) {
1249 bool pair_found = false;
1250 for (int ii = 0; ii < members.Count; ++ii) {
1251 var o_b = members[ii] as Operator;
1252 if (o_b == null || o_b.OperatorType != matching_type)
1255 if (!TypeSpecComparer.IsEqual (o_a.ReturnType, o_b.ReturnType))
1258 if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
1261 found_matched.Add (matching_type);
1267 Report.Error (216, o_a.Location,
1268 "The operator `{0}' requires a matching operator `{1}' to also be defined",
1269 o_a.GetSignatureForError (), Operator.GetName (matching_type));
1273 if (has_equality_or_inequality) {
1275 Report.Warning (660, 2, Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)",
1276 GetSignatureForError ());
1278 if (!HasGetHashCode)
1279 Report.Warning (661, 2, Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()",
1280 GetSignatureForError ());
1284 public override void CreateMetadataName (StringBuilder sb)
1286 if (Parent.MemberName != null) {
1287 Parent.CreateMetadataName (sb);
1289 if (sb.Length != 0) {
1294 sb.Append (MemberName.Basename);
1297 bool CreateTypeBuilder ()
1300 // Sets .size to 1 for structs with no instance fields
1302 int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
1304 var parent_def = Parent as TypeDefinition;
1305 if (parent_def == null) {
1306 var sb = new StringBuilder ();
1307 CreateMetadataName (sb);
1308 TypeBuilder = Module.CreateBuilder (sb.ToString (), TypeAttr, type_size);
1310 TypeBuilder = parent_def.TypeBuilder.DefineNestedType (FilterNestedName (MemberName.Basename), TypeAttr, null, type_size);
1313 if (DeclaringAssembly.Importer != null)
1314 DeclaringAssembly.Importer.AddCompiledType (TypeBuilder, spec);
1316 spec.SetMetaInfo (TypeBuilder);
1317 spec.MemberCache = new MemberCache (this);
1319 TypeParameters parentAllTypeParameters = null;
1320 if (parent_def != null) {
1321 spec.DeclaringType = Parent.CurrentType;
1322 parent_def.MemberCache.AddMember (spec);
1323 parentAllTypeParameters = parent_def.all_type_parameters;
1326 if (MemberName.TypeParameters != null || parentAllTypeParameters != null) {
1327 var tparam_names = CreateTypeParameters (parentAllTypeParameters);
1329 all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names);
1331 if (CurrentTypeParameters != null) {
1332 CurrentTypeParameters.Create (spec, CurrentTypeParametersStartIndex, this);
1333 CurrentTypeParameters.Define (all_tp_builders);
1340 public static string FilterNestedName (string name)
1343 // SRE API does not handle namespaces and types separately but
1344 // determine that from '.' in name. That's problematic because
1345 // dot is valid character for type name. By replacing any '.'
1346 // in name we avoid any ambiguities and never emit metadata
1347 // namespace for nested types
1349 return name.Replace ('.', '_');
1352 string[] CreateTypeParameters (TypeParameters parentAllTypeParameters)
1355 int parent_offset = 0;
1356 if (parentAllTypeParameters != null) {
1357 if (CurrentTypeParameters == null) {
1358 all_type_parameters = parentAllTypeParameters;
1359 return parentAllTypeParameters.GetAllNames ();
1362 names = new string[parentAllTypeParameters.Count + CurrentTypeParameters.Count];
1363 all_type_parameters = new TypeParameters (names.Length);
1364 all_type_parameters.Add (parentAllTypeParameters);
1366 parent_offset = all_type_parameters.Count;
1367 for (int i = 0; i < parent_offset; ++i)
1368 names[i] = all_type_parameters[i].MemberName.Name;
1371 names = new string[CurrentTypeParameters.Count];
1374 for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
1375 if (all_type_parameters != null)
1376 all_type_parameters.Add (MemberName.TypeParameters[i]);
1378 var name = CurrentTypeParameters[i].MemberName.Name;
1379 names[parent_offset + i] = name;
1380 for (int ii = 0; ii < parent_offset + i; ++ii) {
1381 if (names[ii] != name)
1384 var tp = CurrentTypeParameters[i];
1385 var conflict = all_type_parameters[ii];
1387 tp.WarningParentNameConflict (conflict);
1391 if (all_type_parameters == null)
1392 all_type_parameters = CurrentTypeParameters;
1398 public SourceMethodBuilder CreateMethodSymbolEntry ()
1400 if (Module.DeclaringAssembly.SymbolWriter == null || (ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
1403 var source_file = GetCompilationSourceFile ();
1404 if (source_file == null)
1407 return new SourceMethodBuilder (source_file.SymbolUnitEntry);
1411 // Creates a proxy base method call inside this container for hoisted base member calls
1413 public MethodSpec CreateHoistedBaseCallProxy (ResolveContext rc, MethodSpec method)
1415 Method proxy_method;
1418 // One proxy per base method is enough
1420 if (hoisted_base_call_proxies == null) {
1421 hoisted_base_call_proxies = new Dictionary<MethodSpec, Method> ();
1422 proxy_method = null;
1424 hoisted_base_call_proxies.TryGetValue (method, out proxy_method);
1427 if (proxy_method == null) {
1428 string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
1430 MemberName member_name;
1431 TypeArguments targs = null;
1432 TypeSpec return_type = method.ReturnType;
1433 var local_param_types = method.Parameters.Types;
1435 if (method.IsGeneric) {
1437 // Copy all base generic method type parameters info
1439 var hoisted_tparams = method.GenericDefinition.TypeParameters;
1440 var tparams = new TypeParameters ();
1442 targs = new TypeArguments ();
1443 targs.Arguments = new TypeSpec[hoisted_tparams.Length];
1444 for (int i = 0; i < hoisted_tparams.Length; ++i) {
1445 var tp = hoisted_tparams[i];
1446 var tp_name = tp.Name;
1448 tp_name += "_Proxy";
1450 var local_tp = new TypeParameter (tp, null, new MemberName (tp_name, Location), null);
1451 tparams.Add (local_tp);
1453 targs.Add (new SimpleName (tp.Name, Location));
1454 targs.Arguments[i] = local_tp.Type;
1457 member_name = new MemberName (name, tparams, Location);
1460 // Mutate any method type parameters from original
1461 // to newly created hoisted version
1463 var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
1464 return_type = mutator.Mutate (return_type);
1465 local_param_types = mutator.Mutate (local_param_types);
1467 var inflator = new TypeParameterInflator (this, null, hoisted_tparams, targs.Arguments);
1468 for (int i = 0; i < hoisted_tparams.Length; ++i) {
1469 var tp_spec = (TypeParameterSpec) targs.Arguments [i];
1470 tp_spec.InflateConstraints (inflator, tp_spec);
1473 member_name = new MemberName (name);
1476 var base_parameters = new Parameter[method.Parameters.Count];
1477 for (int i = 0; i < base_parameters.Length; ++i) {
1478 var base_param = method.Parameters.FixedParameters[i];
1479 base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
1480 base_param.Name, base_param.ModFlags, null, Location);
1481 base_parameters[i].Resolve (this, i);
1484 var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, local_param_types);
1485 if (method.Parameters.HasArglist) {
1486 cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
1487 cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
1490 // Compiler generated proxy
1491 proxy_method = new Method (this, new TypeExpression (return_type, Location),
1492 Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
1493 member_name, cloned_params, null);
1495 var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
1496 IsCompilerGenerated = true
1499 var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
1500 mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
1502 mg.SetTypeArguments (rc, targs);
1504 // Get all the method parameters and pass them as arguments
1505 var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
1506 Statement statement;
1507 if (method.ReturnType.Kind == MemberKind.Void)
1508 statement = new StatementExpression (real_base_call);
1510 statement = new Return (real_base_call, Location);
1512 block.AddStatement (statement);
1513 proxy_method.Block = block;
1515 members.Add (proxy_method);
1516 proxy_method.Define ();
1517 proxy_method.PrepareEmit ();
1519 hoisted_base_call_proxies.Add (method, proxy_method);
1522 return proxy_method.Spec;
1525 protected bool DefineBaseTypes ()
1527 if (IsPartialPart && Kind == MemberKind.Class)
1530 return DoDefineBaseType ();
1533 bool DoDefineBaseType ()
1535 iface_exprs = ResolveBaseTypes (out base_type_expr);
1538 if (IsPartialPart) {
1539 set_base_type = false;
1541 if (base_type_expr != null) {
1542 if (PartialContainer.base_type_expr != null && PartialContainer.base_type != base_type) {
1543 Report.SymbolRelatedToPreviousError (base_type_expr.Location, "");
1544 Report.Error (263, Location,
1545 "Partial declarations of `{0}' must not specify different base classes",
1546 GetSignatureForError ());
1548 PartialContainer.base_type_expr = base_type_expr;
1549 PartialContainer.base_type = base_type;
1550 set_base_type = true;
1554 if (iface_exprs != null) {
1555 if (PartialContainer.iface_exprs == null)
1556 PartialContainer.iface_exprs = iface_exprs;
1558 var ifaces = new List<TypeSpec> (PartialContainer.iface_exprs);
1559 foreach (var iface_partial in iface_exprs) {
1560 if (ifaces.Contains (iface_partial))
1563 ifaces.Add (iface_partial);
1566 PartialContainer.iface_exprs = ifaces.ToArray ();
1570 PartialContainer.members.AddRange (members);
1571 if (containers != null) {
1572 if (PartialContainer.containers == null)
1573 PartialContainer.containers = new List<TypeContainer> ();
1575 PartialContainer.containers.AddRange (containers);
1578 if (PrimaryConstructorParameters != null) {
1579 if (PartialContainer.PrimaryConstructorParameters != null) {
1580 Report.Error (8036, Location, "Only one part of a partial type can declare primary constructor parameters");
1582 PartialContainer.PrimaryConstructorParameters = PrimaryConstructorParameters;
1586 members_defined = members_defined_ok = true;
1587 caching_flags |= Flags.CloseTypeCreated;
1589 set_base_type = true;
1592 var cycle = CheckRecursiveDefinition (this);
1593 if (cycle != null) {
1594 Report.SymbolRelatedToPreviousError (cycle);
1595 if (this is Interface) {
1596 Report.Error (529, Location,
1597 "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
1598 GetSignatureForError (), cycle.GetSignatureForError ());
1601 PartialContainer.iface_exprs = null;
1603 Report.Error (146, Location,
1604 "Circular base class dependency involving `{0}' and `{1}'",
1605 GetSignatureForError (), cycle.GetSignatureForError ());
1608 PartialContainer.base_type = null;
1612 if (iface_exprs != null) {
1613 if (!PrimaryConstructorBaseArgumentsStart.IsNull) {
1614 Report.Error (8049, PrimaryConstructorBaseArgumentsStart, "Implemented interfaces cannot have arguments");
1617 foreach (var iface_type in iface_exprs) {
1618 // Prevents a crash, the interface might not have been resolved: 442144
1619 if (iface_type == null)
1622 if (!spec.AddInterfaceDefined (iface_type))
1625 TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
1629 if (Kind == MemberKind.Interface) {
1630 spec.BaseType = Compiler.BuiltinTypes.Object;
1634 if (set_base_type) {
1639 // Base type of partial container has to be resolved before we
1640 // resolve any nested types of the container. We need to know
1641 // partial parts because the base type can be specified in file
1642 // defined after current container
1644 if (class_partial_parts != null) {
1645 foreach (var pp in class_partial_parts) {
1646 if (pp.PrimaryConstructorBaseArguments != null)
1647 PrimaryConstructorBaseArguments = pp.PrimaryConstructorBaseArguments;
1649 pp.DoDefineBaseType ();
1659 if (base_type == null) {
1660 TypeBuilder.SetParent (null);
1664 if (spec.BaseType == base_type)
1667 spec.BaseType = base_type;
1670 spec.UpdateInflatedInstancesBaseType ();
1672 // Set base type after type creation
1673 TypeBuilder.SetParent (base_type.GetMetaInfo ());
1676 public override void ExpandBaseInterfaces ()
1678 DoResolveTypeParameters ();
1681 DoExpandBaseInterfaces ();
1683 base.ExpandBaseInterfaces ();
1686 public void DoExpandBaseInterfaces ()
1688 if ((caching_flags & Flags.InterfacesExpanded) != 0)
1691 caching_flags |= Flags.InterfacesExpanded;
1694 // Expand base interfaces. It cannot be done earlier because all partial
1695 // interface parts need to be defined before the type they are used from
1697 if (iface_exprs != null) {
1698 foreach (var iface in iface_exprs) {
1702 var td = iface.MemberDefinition as TypeDefinition;
1704 td.DoExpandBaseInterfaces ();
1706 if (iface.Interfaces == null)
1709 foreach (var biface in iface.Interfaces) {
1710 if (spec.AddInterfaceDefined (biface)) {
1711 TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ());
1718 // Include all base type interfaces too, see ImportTypeBase for details
1720 if (base_type != null) {
1721 var td = base_type.MemberDefinition as TypeDefinition;
1723 td.DoExpandBaseInterfaces ();
1726 // Simply use base interfaces only, they are all expanded which makes
1727 // it easy to handle generic type argument propagation with single
1730 // interface IA<T> : IB<T>
1731 // interface IB<U> : IC<U>
1734 if (base_type.Interfaces != null) {
1735 foreach (var iface in base_type.Interfaces) {
1736 spec.AddInterfaceDefined (iface);
1742 public override void PrepareEmit ()
1744 if ((caching_flags & Flags.CloseTypeCreated) != 0)
1747 foreach (var member in members) {
1748 var pbm = member as MemberBase;
1753 base.PrepareEmit ();
1757 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1759 public override bool CreateContainer ()
1761 if (TypeBuilder != null)
1767 if (IsPartialPart) {
1768 spec = PartialContainer.spec;
1769 TypeBuilder = PartialContainer.TypeBuilder;
1770 all_tp_builders = PartialContainer.all_tp_builders;
1771 all_type_parameters = PartialContainer.all_type_parameters;
1773 if (!CreateTypeBuilder ()) {
1779 return base.CreateContainer ();
1782 protected override void DoDefineContainer ()
1788 // Replaces normal spec with predefined one when compiling corlib
1789 // and this type container defines predefined type
1791 public void SetPredefinedSpec (BuiltinTypeSpec spec)
1793 // When compiling build-in types we start with two
1794 // version of same type. One is of BuiltinTypeSpec and
1795 // second one is ordinary TypeSpec. The unification
1796 // happens at later stage when we know which type
1797 // really matches the builtin type signature. However
1798 // that means TypeSpec create during CreateType of this
1799 // type has to be replaced with builtin one
1801 spec.SetMetaInfo (TypeBuilder);
1802 spec.MemberCache = this.spec.MemberCache;
1803 spec.DeclaringType = this.spec.DeclaringType;
1806 current_type = null;
1807 if (class_partial_parts != null) {
1808 foreach (var part in class_partial_parts) {
1810 part.current_type = null;
1815 public override void RemoveContainer (TypeContainer cont)
1817 base.RemoveContainer (cont);
1818 Members.Remove (cont);
1819 Cache.Remove (cont.MemberName.Basename);
1822 protected virtual bool DoResolveTypeParameters ()
1824 var tparams = MemberName.TypeParameters;
1825 if (tparams == null)
1828 var base_context = new BaseContext (this);
1829 for (int i = 0; i < tparams.Count; ++i) {
1830 var tp = tparams[i];
1832 if (!tp.ResolveConstraints (base_context)) {
1837 if (IsPartialPart) {
1838 var pc_tp = PartialContainer.CurrentTypeParameters [i];
1840 tp.Create (spec, this);
1843 if (tp.OptAttributes != null) {
1844 if (pc_tp.OptAttributes == null)
1845 pc_tp.OptAttributes = tp.OptAttributes;
1847 pc_tp.OptAttributes.Attrs.AddRange (tp.OptAttributes.Attrs);
1852 if (IsPartialPart) {
1853 PartialContainer.CurrentTypeParameters.UpdateConstraints (this);
1859 TypeSpec CheckRecursiveDefinition (TypeDefinition tc)
1861 if (InTransit != null)
1866 if (base_type != null) {
1867 var ptc = base_type.MemberDefinition as TypeDefinition;
1868 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1872 if (iface_exprs != null && this is Interface) {
1873 foreach (var iface in iface_exprs) {
1874 // the interface might not have been resolved, prevents a crash, see #442144
1877 var ptc = iface.MemberDefinition as Interface;
1878 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1883 if (!IsTopLevel && Parent.PartialContainer.CheckRecursiveDefinition (this) != null)
1891 /// Populates our TypeBuilder with fields and methods
1893 public sealed override bool Define ()
1895 if (members_defined)
1896 return members_defined_ok;
1898 members_defined_ok = DoDefineMembers ();
1899 members_defined = true;
1903 return members_defined_ok;
1906 protected virtual bool DoDefineMembers ()
1908 Debug.Assert (!IsPartialPart);
1910 if (iface_exprs != null) {
1911 foreach (var iface_type in iface_exprs) {
1912 if (iface_type == null)
1915 // Ensure the base is always setup
1916 var compiled_iface = iface_type.MemberDefinition as Interface;
1917 if (compiled_iface != null)
1918 compiled_iface.Define ();
1920 iface_type.CheckObsoleteness (this, Location);
1922 if (iface_type.Arity > 0) {
1923 // TODO: passing `this' is wrong, should be base type iface instead
1924 VarianceDecl.CheckTypeVariance (iface_type, Variance.Covariant, this);
1926 if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) {
1927 Report.Error (1966, Location,
1928 "`{0}': cannot implement a dynamic interface `{1}'",
1929 GetSignatureForError (), iface_type.GetSignatureForError ());
1934 if (iface_type.IsGenericOrParentIsGeneric) {
1935 foreach (var prev_iface in iface_exprs) {
1936 if (prev_iface == iface_type || prev_iface == null)
1939 if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
1942 Report.Error (695, Location,
1943 "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
1944 GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
1949 if (Kind == MemberKind.Interface) {
1950 foreach (var iface in spec.Interfaces) {
1951 MemberCache.AddInterface (iface);
1956 if (base_type != null) {
1958 // Run checks skipped during DefineType (e.g FullNamedExpression::ResolveAsType)
1960 if (base_type_expr != null) {
1961 base_type.CheckObsoleteness (this, base_type_expr.Location);
1963 if (IsGenericOrParentIsGeneric && base_type.IsAttribute) {
1964 Report.Error (698, base_type_expr.Location,
1965 "A generic type cannot derive from `{0}' because it is an attribute class",
1966 base_type.GetSignatureForError ());
1970 var baseContainer = base_type.MemberDefinition as ClassOrStruct;
1971 if (baseContainer != null) {
1972 baseContainer.Define ();
1975 // It can trigger define of this type (for generic types only)
1977 if (HasMembersDefined)
1982 if (Kind == MemberKind.Struct || Kind == MemberKind.Class) {
1983 pending = PendingImplementation.GetPendingImplementations (this);
1986 var count = members.Count;
1987 for (int i = 0; i < count; ++i) {
1988 var mc = members[i] as InterfaceMemberBase;
1989 if (mc == null || !mc.IsExplicitImpl)
1994 } catch (Exception e) {
1995 throw new InternalErrorException (mc, e);
1999 for (int i = 0; i < count; ++i) {
2000 var mc = members[i] as InterfaceMemberBase;
2001 if (mc != null && mc.IsExplicitImpl)
2004 if (members[i] is TypeContainer)
2008 members[i].Define ();
2009 } catch (Exception e) {
2010 throw new InternalErrorException (members[i], e);
2015 CheckPairedOperators ();
2018 ComputeIndexerName();
2020 if (HasEquals && !HasGetHashCode) {
2021 Report.Warning (659, 3, Location,
2022 "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ());
2025 if (Kind == MemberKind.Interface && iface_exprs != null) {
2026 MemberCache.RemoveHiddenMembers (spec);
2032 void ComputeIndexerName ()
2034 var indexers = MemberCache.FindMembers (spec, MemberCache.IndexerNameAlias, true);
2035 if (indexers == null)
2038 string class_indexer_name = null;
2041 // Check normal indexers for consistent name, explicit interface implementation
2042 // indexers are ignored
2044 foreach (var indexer in indexers) {
2046 // FindMembers can return unfiltered full hierarchy names
2048 if (indexer.DeclaringType != spec)
2051 has_normal_indexers = true;
2053 if (class_indexer_name == null) {
2054 indexer_name = class_indexer_name = indexer.Name;
2058 if (indexer.Name != class_indexer_name)
2059 Report.Error (668, ((Indexer)indexer.MemberDefinition).Location,
2060 "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
2064 void EmitIndexerName ()
2066 if (!has_normal_indexers)
2069 var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
2073 var encoder = new AttributeEncoder ();
2074 encoder.Encode (GetAttributeDefaultMember ());
2075 encoder.EncodeEmptyNamedArguments ();
2077 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
2080 public override void VerifyMembers ()
2083 // Check for internal or private fields that were never assigned
2085 if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) {
2086 bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
2087 foreach (var member in members) {
2088 if (member is Event) {
2090 // An event can be assigned from same class only, report
2091 // this warning for all accessibility modes
2093 if (!member.IsUsed && !PartialContainer.HasStructLayout)
2094 Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ());
2099 if ((member.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
2100 if (is_type_exposed)
2103 member.SetIsUsed ();
2106 var f = member as Field;
2110 if (!member.IsUsed) {
2111 if (!PartialContainer.HasStructLayout) {
2112 if ((member.caching_flags & Flags.IsAssigned) == 0) {
2113 Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ());
2115 Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used",
2116 member.GetSignatureForError ());
2123 if ((f.caching_flags & Flags.IsAssigned) != 0)
2127 // Only report 649 on level 4
2129 if (Compiler.Settings.WarningLevel < 4)
2133 // Don't be pedantic when type requires specific layout
2135 if (f.OptAttributes != null || PartialContainer.HasStructLayout)
2138 Constant c = New.Constantify (f.MemberType, f.Location);
2141 value = c.GetValueAsLiteral ();
2142 } else if (TypeSpec.IsReferenceType (f.MemberType)) {
2149 value = " `" + value + "'";
2151 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
2152 f.GetSignatureForError (), value);
2156 base.VerifyMembers ();
2159 public override void Emit ()
2161 if (OptAttributes != null)
2162 OptAttributes.Emit ();
2164 if (!IsCompilerGenerated) {
2166 MemberSpec candidate;
2167 bool overrides = false;
2168 var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
2169 if (conflict_symbol == null && candidate == null) {
2170 if ((ModFlags & Modifiers.NEW) != 0)
2171 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
2172 GetSignatureForError ());
2174 if ((ModFlags & Modifiers.NEW) == 0) {
2175 if (candidate == null)
2176 candidate = conflict_symbol;
2178 Report.SymbolRelatedToPreviousError (candidate);
2179 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
2180 GetSignatureForError (), candidate.GetSignatureForError ());
2185 // Run constraints check on all possible generic types
2186 if (base_type != null && base_type_expr != null) {
2187 ConstraintChecker.Check (this, base_type, base_type_expr.Location);
2190 if (iface_exprs != null) {
2191 foreach (var iface_type in iface_exprs) {
2192 if (iface_type == null)
2195 ConstraintChecker.Check (this, iface_type, Location); // TODO: Location is wrong
2200 if (all_tp_builders != null) {
2201 int current_starts_index = CurrentTypeParametersStartIndex;
2202 for (int i = 0; i < all_tp_builders.Length; i++) {
2203 if (i < current_starts_index) {
2204 all_type_parameters[i].EmitConstraints (all_tp_builders [i]);
2206 var tp = CurrentTypeParameters [i - current_starts_index];
2207 tp.CheckGenericConstraints (!IsObsolete);
2213 if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2214 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (TypeBuilder);
2217 if ((TypeBuilder.Attributes & TypeAttributes.StringFormatMask) == 0 && Module.HasDefaultCharSet)
2218 TypeBuilder.__SetAttributes (TypeBuilder.Attributes | Module.DefaultCharSetType);
2223 for (int i = 0; i < members.Count; i++) {
2225 if ((m.caching_flags & Flags.CloseTypeCreated) != 0)
2232 CheckAttributeClsCompliance ();
2234 if (pending != null)
2235 pending.VerifyPendingMethods ();
2239 void CheckAttributeClsCompliance ()
2241 if (!spec.IsAttribute || !IsExposedFromAssembly () || !Compiler.Settings.VerifyClsCompliance || !IsClsComplianceRequired ())
2244 foreach (var m in members) {
2245 var c = m as Constructor;
2249 if (c.HasCompliantArgs)
2253 Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2256 public sealed override void EmitContainer ()
2258 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2264 public override void CloseContainer ()
2266 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2269 // Close base type container first to avoid TypeLoadException
2270 if (spec.BaseType != null) {
2271 var btype = spec.BaseType.MemberDefinition as TypeContainer;
2272 if (btype != null) {
2273 btype.CloseContainer ();
2275 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2281 caching_flags |= Flags.CloseTypeCreated;
2282 TypeBuilder.CreateType ();
2283 } catch (TypeLoadException) {
2285 // This is fine, the code still created the type
2287 } catch (Exception e) {
2288 throw new InternalErrorException (this, e);
2291 base.CloseContainer ();
2294 initialized_fields = null;
2295 initialized_static_fields = null;
2297 OptAttributes = null;
2301 // Performs the validation on a Method's modifiers (properties have
2302 // the same properties).
2304 // TODO: Why is it not done at parse stage, move to Modifiers::Check
2306 public bool MethodModifiersValid (MemberCore mc)
2308 const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2309 const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2311 var flags = mc.ModFlags;
2314 // At most one of static, virtual or override
2316 if ((flags & Modifiers.STATIC) != 0){
2317 if ((flags & vao) != 0){
2318 Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2319 mc.GetSignatureForError ());
2324 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2325 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2326 mc.GetSignatureForError ());
2331 // If the declaration includes the abstract modifier, then the
2332 // declaration does not include static, virtual or extern
2334 if ((flags & Modifiers.ABSTRACT) != 0){
2335 if ((flags & Modifiers.EXTERN) != 0){
2337 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2341 if ((flags & Modifiers.SEALED) != 0) {
2342 Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2346 if ((flags & Modifiers.VIRTUAL) != 0){
2347 Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2351 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2352 Report.SymbolRelatedToPreviousError (this);
2353 Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2354 mc.GetSignatureForError (), GetSignatureForError ());
2359 if ((flags & Modifiers.PRIVATE) != 0){
2360 if ((flags & vao) != 0){
2361 Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2366 if ((flags & Modifiers.SEALED) != 0){
2367 if ((flags & Modifiers.OVERRIDE) == 0){
2368 Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2376 protected override bool VerifyClsCompliance ()
2378 if (!base.VerifyClsCompliance ())
2381 // Check all container names for user classes
2382 if (Kind != MemberKind.Delegate)
2383 MemberCache.VerifyClsCompliance (Definition, Report);
2385 if (BaseType != null && !BaseType.IsCLSCompliant ()) {
2386 Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant",
2387 GetSignatureForError (), BaseType.GetSignatureForError ());
2393 /// Performs checks for an explicit interface implementation. First it
2394 /// checks whether the `interface_type' is a base inteface implementation.
2395 /// Then it checks whether `name' exists in the interface type.
2397 public bool VerifyImplements (InterfaceMemberBase mb)
2399 var ifaces = PartialContainer.Interfaces;
2400 if (ifaces != null) {
2401 foreach (TypeSpec t in ifaces){
2402 if (t == mb.InterfaceType || t == null)
2405 var expanded_base = t.Interfaces;
2406 if (expanded_base == null)
2409 foreach (var bt in expanded_base) {
2410 if (bt == mb.InterfaceType)
2416 Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2417 Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2418 mb.GetSignatureForError (), mb.InterfaceType.GetSignatureForError ());
2423 // Used for visiblity checks to tests whether this definition shares
2424 // base type baseType, it does member-definition search
2426 public bool IsBaseTypeDefinition (TypeSpec baseType)
2428 // RootContext check
2429 if (TypeBuilder == null)
2434 if (type.MemberDefinition == baseType.MemberDefinition)
2437 type = type.BaseType;
2438 } while (type != null);
2443 public override bool IsClsComplianceRequired ()
2446 return PartialContainer.IsClsComplianceRequired ();
2448 return base.IsClsComplianceRequired ();
2451 bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
2453 return Module.DeclaringAssembly == assembly;
2456 public virtual bool IsUnmanagedType ()
2461 public void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache)
2463 throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ());
2467 // Public function used to locate types.
2469 // Returns: Type or null if they type can not be found.
2471 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
2473 FullNamedExpression e;
2474 if (arity == 0 && Cache.TryGetValue (name, out e) && mode != LookupMode.IgnoreAccessibility)
2480 var tp = CurrentTypeParameters;
2482 TypeParameter tparam = tp.Find (name);
2484 e = new TypeParameterExpr (tparam, Location.Null);
2489 TypeSpec t = LookupNestedTypeInHierarchy (name, arity);
2491 if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility))
2492 e = new TypeExpression (t, Location.Null);
2494 var errors = Compiler.Report.Errors;
2495 e = Parent.LookupNamespaceOrType (name, arity, mode, loc);
2497 // TODO: LookupNamespaceOrType does more than just lookup. The result
2498 // cannot be cached or the error reporting won't happen
2499 if (errors != Compiler.Report.Errors)
2504 // TODO MemberCache: How to cache arity stuff ?
2505 if (arity == 0 && mode == LookupMode.Normal)
2511 TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
2513 // Has any nested type
2514 // Does not work, because base type can have
2515 //if (PartialContainer.Types == null)
2518 var container = PartialContainer.CurrentType;
2519 return MemberCache.FindNestedType (container, name, arity, false);
2522 public void Mark_HasEquals ()
2524 cached_method |= CachedMethods.Equals;
2527 public void Mark_HasGetHashCode ()
2529 cached_method |= CachedMethods.GetHashCode;
2532 public override void WriteDebugSymbol (MonoSymbolFile file)
2537 foreach (var m in members) {
2538 m.WriteDebugSymbol (file);
2543 /// Method container contains Equals method
2545 public bool HasEquals {
2547 return (cached_method & CachedMethods.Equals) != 0;
2552 /// Method container contains GetHashCode method
2554 public bool HasGetHashCode {
2556 return (cached_method & CachedMethods.GetHashCode) != 0;
2560 public bool HasStaticFieldInitializer {
2562 return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
2566 cached_method |= CachedMethods.HasStaticFieldInitializer;
2568 cached_method &= ~CachedMethods.HasStaticFieldInitializer;
2572 public override string DocCommentHeader {
2573 get { return "T:"; }
2577 public abstract class ClassOrStruct : TypeDefinition
2579 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2581 SecurityType declarative_security;
2582 protected Constructor generated_primary_constructor;
2584 protected ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
2585 : base (parent, name, attrs, kind)
2589 public ToplevelBlock PrimaryConstructorBlock { get; set; }
2591 protected override TypeAttributes TypeAttr {
2593 TypeAttributes ta = base.TypeAttr;
2594 if (!has_static_constructor)
2595 ta |= TypeAttributes.BeforeFieldInit;
2597 if (Kind == MemberKind.Class) {
2598 ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
2600 ta |= StaticClassAttribute;
2602 ta |= TypeAttributes.SequentialLayout;
2609 public override void AddNameToContainer (MemberCore symbol, string name)
2611 if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) {
2612 if (symbol is TypeParameter) {
2613 Report.Error (694, symbol.Location,
2614 "Type parameter `{0}' has same name as containing type, or method",
2615 symbol.GetSignatureForError ());
2619 InterfaceMemberBase imb = symbol as InterfaceMemberBase;
2620 if (imb == null || !imb.IsExplicitImpl) {
2621 Report.SymbolRelatedToPreviousError (this);
2622 Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2623 symbol.GetSignatureForError ());
2628 base.AddNameToContainer (symbol, name);
2631 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2633 if (a.IsValidSecurityAttribute ()) {
2634 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2638 if (a.Type == pa.StructLayout) {
2639 PartialContainer.HasStructLayout = true;
2640 if (a.IsExplicitLayoutKind ())
2641 PartialContainer.HasExplicitLayout = true;
2644 if (a.Type == pa.Dynamic) {
2645 a.Error_MisusedDynamicAttribute ();
2649 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2653 /// Defines the default constructors
2655 protected virtual Constructor DefineDefaultConstructor (bool is_static)
2657 // The default instance constructor is public
2658 // If the class is abstract, the default constructor is protected
2659 // The default static constructor is private
2662 ParametersCompiled parameters = null;
2664 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2665 parameters = ParametersCompiled.EmptyReadOnlyParameters;
2667 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2668 parameters = PrimaryConstructorParameters ?? ParametersCompiled.EmptyReadOnlyParameters;
2671 var c = new Constructor (this, MemberName.Name, mods, null, parameters, Location);
2672 if (Kind == MemberKind.Class)
2673 c.Initializer = new GeneratedBaseInitializer (Location, PrimaryConstructorBaseArguments);
2675 if (PrimaryConstructorParameters != null && !is_static) {
2676 c.IsPrimaryConstructor = true;
2677 c.caching_flags |= Flags.MethodOverloadsExist;
2680 AddConstructor (c, true);
2681 if (PrimaryConstructorBlock == null) {
2682 c.Block = new ToplevelBlock (Compiler, parameters, Location) {
2683 IsCompilerGenerated = true
2686 c.Block = PrimaryConstructorBlock;
2692 protected override bool DoDefineMembers ()
2694 CheckProtectedModifier ();
2696 if (PrimaryConstructorParameters != null) {
2698 foreach (Parameter p in PrimaryConstructorParameters.FixedParameters) {
2699 if (p.Name == MemberName.Name) {
2700 Report.Error (8039, p.Location, "Primary constructor of type `{0}' has parameter of same name as containing type",
2701 GetSignatureForError ());
2704 if (CurrentTypeParameters != null) {
2705 for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
2706 var tp = CurrentTypeParameters [i];
2707 if (p.Name == tp.Name) {
2708 Report.Error (8038, p.Location, "Primary constructor of type `{0}' has parameter of same name as type parameter `{1}'",
2709 GetSignatureForError (), p.GetSignatureForError ());
2716 base.DoDefineMembers ();
2721 public override void PrepareEmit ()
2723 var s = this as Struct;
2724 if (s == null || !s.HasUnmanagedCheckDone) {
2725 for (int i = 0; i < Members.Count; ++i) {
2726 var f = Members [i] as Field;
2727 if (f == null || f.MemberType == null || !f.MemberType.IsPointer)
2730 TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
2734 base.PrepareEmit ();
2737 public override void Emit ()
2739 if (!has_static_constructor && HasStaticFieldInitializer) {
2740 var c = DefineDefaultConstructor (true);
2746 if (declarative_security != null) {
2747 foreach (var de in declarative_security) {
2749 TypeBuilder.__AddDeclarativeSecurity (de);
2751 TypeBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2759 public sealed class Class : ClassOrStruct
2761 const Modifiers AllowedModifiers =
2764 Modifiers.PROTECTED |
2765 Modifiers.INTERNAL |
2767 Modifiers.ABSTRACT |
2772 public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2773 : base (parent, name, attrs, MemberKind.Class)
2775 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2776 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
2777 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2780 public override void Accept (StructuralVisitor visitor)
2782 visitor.Visit (this);
2785 public override void SetBaseTypes (List<FullNamedExpression> baseTypes)
2787 var pmn = MemberName;
2788 if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null)
2789 Report.Error (537, Location,
2790 "The class System.Object cannot have a base class or implement an interface.");
2792 base.SetBaseTypes (baseTypes);
2795 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2797 if (a.Type == pa.AttributeUsage) {
2798 if (!BaseType.IsAttribute && spec.BuiltinType != BuiltinTypeSpec.Type.Attribute) {
2799 Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2803 if (a.Type == pa.Conditional && !BaseType.IsAttribute) {
2804 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2808 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
2809 a.Error_MissingGuidAttribute ();
2813 if (a.Type == pa.Extension) {
2814 a.Error_MisusedExtensionAttribute ();
2818 if (a.Type.IsConditionallyExcluded (this))
2821 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2824 public override AttributeTargets AttributeTargets {
2826 return AttributeTargets.Class;
2830 protected override bool DoDefineMembers ()
2832 if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2833 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2836 if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2837 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2841 if (PrimaryConstructorParameters != null) {
2842 Report.Error (-800, Location, "`{0}': Static classes cannot have primary constructor", GetSignatureForError ());
2843 PrimaryConstructorParameters = null;
2846 foreach (var m in Members) {
2847 if (m is Operator) {
2848 Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2852 if (m is Destructor) {
2853 Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2858 Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2862 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is TypeContainer)
2865 if (m is Constructor) {
2866 Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2870 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2873 if (!PartialContainer.HasInstanceConstructor || PrimaryConstructorParameters != null)
2874 generated_primary_constructor = DefineDefaultConstructor (false);
2877 return base.DoDefineMembers ();
2880 public override void Emit ()
2884 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
2885 Module.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
2887 if (base_type != null && base_type.HasDynamicElement) {
2888 Module.PredefinedAttributes.Dynamic.EmitAttribute (TypeBuilder, base_type, Location);
2892 public override void GetCompletionStartingWith (string prefix, List<string> results)
2894 base.GetCompletionStartingWith (prefix, results);
2897 while (bt != null) {
2898 results.AddRange (MemberCache.GetCompletitionMembers (this, bt, prefix).Where (l => l.IsStatic).Select (l => l.Name));
2903 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
2905 var ifaces = base.ResolveBaseTypes (out base_class);
2907 if (base_class == null) {
2908 if (spec.BuiltinType != BuiltinTypeSpec.Type.Object)
2909 base_type = Compiler.BuiltinTypes.Object;
2911 if (base_type.IsGenericParameter){
2912 Report.Error (689, base_class.Location, "`{0}': Cannot derive from type parameter `{1}'",
2913 GetSignatureForError (), base_type.GetSignatureForError ());
2914 } else if (base_type.IsStatic) {
2915 Report.SymbolRelatedToPreviousError (base_type);
2916 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
2917 GetSignatureForError (), base_type.GetSignatureForError ());
2918 } else if (base_type.IsSealed) {
2919 Report.SymbolRelatedToPreviousError (base_type);
2920 Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
2921 GetSignatureForError (), base_type.GetSignatureForError ());
2922 } else if (PartialContainer.IsStatic && base_type.BuiltinType != BuiltinTypeSpec.Type.Object) {
2923 Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2924 GetSignatureForError (), base_type.GetSignatureForError ());
2927 switch (base_type.BuiltinType) {
2928 case BuiltinTypeSpec.Type.Enum:
2929 case BuiltinTypeSpec.Type.ValueType:
2930 case BuiltinTypeSpec.Type.MulticastDelegate:
2931 case BuiltinTypeSpec.Type.Delegate:
2932 case BuiltinTypeSpec.Type.Array:
2933 if (!(spec is BuiltinTypeSpec)) {
2934 Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
2935 GetSignatureForError (), base_type.GetSignatureForError ());
2937 base_type = Compiler.BuiltinTypes.Object;
2942 if (!IsAccessibleAs (base_type)) {
2943 Report.SymbolRelatedToPreviousError (base_type);
2944 Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
2945 base_type.GetSignatureForError (), GetSignatureForError ());
2949 if (PartialContainer.IsStatic && ifaces != null) {
2950 foreach (var t in ifaces)
2951 Report.SymbolRelatedToPreviousError (t);
2952 Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2958 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2959 /// Valid only for attribute classes.
2960 public override string[] ConditionalConditions ()
2962 if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
2965 caching_flags &= ~Flags.Excluded_Undetected;
2967 if (OptAttributes == null)
2970 Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
2974 string[] conditions = new string[attrs.Length];
2975 for (int i = 0; i < conditions.Length; ++i)
2976 conditions[i] = attrs[i].GetConditionalAttributeValue ();
2978 caching_flags |= Flags.Excluded;
2983 public sealed class Struct : ClassOrStruct
2985 bool is_unmanaged, has_unmanaged_check_done, requires_delayed_unmanagedtype_check;
2989 // Modifiers allowed in a struct declaration
2991 const Modifiers AllowedModifiers =
2994 Modifiers.PROTECTED |
2995 Modifiers.INTERNAL |
2999 public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
3000 : base (parent, name, attrs, MemberKind.Struct)
3002 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
3003 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
3004 spec = new TypeSpec (Kind, null, this, null, ModFlags);
3007 public override AttributeTargets AttributeTargets {
3009 return AttributeTargets.Struct;
3013 public override void Accept (StructuralVisitor visitor)
3015 visitor.Visit (this);
3018 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
3020 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
3023 // When struct constains fixed fixed and struct layout has explicitly
3024 // set CharSet, its value has to be propagated to compiler generated
3027 if (a.Type == pa.StructLayout) {
3028 var value = a.GetNamedValue ("CharSet");
3032 for (int i = 0; i < Members.Count; ++i) {
3033 FixedField ff = Members [i] as FixedField;
3037 ff.CharSetValue = (CharSet) System.Enum.Parse (typeof (CharSet), value.GetValue ().ToString ());
3042 bool CheckStructCycles ()
3048 foreach (var member in Members) {
3049 var field = member as Field;
3053 TypeSpec ftype = field.Spec.MemberType;
3054 if (!ftype.IsStruct)
3057 if (ftype is BuiltinTypeSpec)
3060 foreach (var targ in ftype.TypeArguments) {
3061 if (!CheckFieldTypeCycle (targ)) {
3062 Report.Error (523, field.Location,
3063 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
3064 field.GetSignatureForError (), ftype.GetSignatureForError ());
3070 // Static fields of exactly same type are allowed
3072 if (field.IsStatic && ftype == CurrentType)
3075 if (!CheckFieldTypeCycle (ftype)) {
3076 Report.Error (523, field.Location,
3077 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
3078 field.GetSignatureForError (), ftype.GetSignatureForError ());
3087 static bool CheckFieldTypeCycle (TypeSpec ts)
3089 var fts = ts.MemberDefinition as Struct;
3093 return fts.CheckStructCycles ();
3096 protected override bool DoDefineMembers ()
3098 var res = base.DoDefineMembers ();
3100 if (PrimaryConstructorParameters != null || (initialized_fields != null && !HasUserDefaultConstructor ())) {
3101 generated_primary_constructor = DefineDefaultConstructor (false);
3102 generated_primary_constructor.Define ();
3108 public override void Emit ()
3110 CheckStructCycles ();
3115 public bool HasUnmanagedCheckDone {
3117 return has_unmanaged_check_done;
3121 bool HasUserDefaultConstructor ()
3123 foreach (var m in PartialContainer.Members) {
3124 var c = m as Constructor;
3128 if (!c.IsStatic && c.ParameterInfo.IsEmpty)
3135 public override bool IsUnmanagedType ()
3137 if (has_unmanaged_check_done)
3138 return is_unmanaged;
3140 if (requires_delayed_unmanagedtype_check)
3143 var parent_def = Parent.PartialContainer;
3144 if (parent_def != null && parent_def.IsGenericOrParentIsGeneric) {
3145 has_unmanaged_check_done = true;
3149 if (first_nonstatic_field != null) {
3150 requires_delayed_unmanagedtype_check = true;
3152 foreach (var member in Members) {
3153 var f = member as Field;
3160 // It can happen when recursive unmanaged types are defined
3161 // struct S { S* s; }
3162 TypeSpec mt = f.MemberType;
3170 has_unmanaged_check_done = true;
3174 has_unmanaged_check_done = true;
3177 is_unmanaged = true;
3181 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
3183 var ifaces = base.ResolveBaseTypes (out base_class);
3184 base_type = Compiler.BuiltinTypes.ValueType;
3192 public sealed class Interface : TypeDefinition {
3195 /// Modifiers allowed in a class declaration
3197 const Modifiers AllowedModifiers =
3200 Modifiers.PROTECTED |
3201 Modifiers.INTERNAL |
3205 public Interface (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
3206 : base (parent, name, attrs, MemberKind.Interface)
3208 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
3210 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
3211 spec = new TypeSpec (Kind, null, this, null, ModFlags);
3216 public override AttributeTargets AttributeTargets {
3218 return AttributeTargets.Interface;
3222 protected override TypeAttributes TypeAttr {
3224 const TypeAttributes DefaultTypeAttributes =
3225 TypeAttributes.AutoLayout |
3226 TypeAttributes.Abstract |
3227 TypeAttributes.Interface;
3229 return base.TypeAttr | DefaultTypeAttributes;
3235 public override void Accept (StructuralVisitor visitor)
3237 visitor.Visit (this);
3240 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
3242 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
3243 a.Error_MissingGuidAttribute ();
3247 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
3250 protected override bool VerifyClsCompliance ()
3252 if (!base.VerifyClsCompliance ())
3255 if (iface_exprs != null) {
3256 foreach (var iface in iface_exprs) {
3257 if (iface.IsCLSCompliant ())
3260 Report.SymbolRelatedToPreviousError (iface);
3261 Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3262 GetSignatureForError (), iface.GetSignatureForError ());
3270 public abstract class InterfaceMemberBase : MemberBase
3273 // Common modifiers allowed in a class declaration
3275 protected const Modifiers AllowedModifiersClass =
3278 Modifiers.PROTECTED |
3279 Modifiers.INTERNAL |
3284 Modifiers.OVERRIDE |
3285 Modifiers.ABSTRACT |
3290 // Common modifiers allowed in a struct declaration
3292 protected const Modifiers AllowedModifiersStruct =
3295 Modifiers.PROTECTED |
3296 Modifiers.INTERNAL |
3299 Modifiers.OVERRIDE |
3304 // Common modifiers allowed in a interface declaration
3306 protected const Modifiers AllowedModifiersInterface =
3311 // Whether this is an interface member.
3313 public bool IsInterface;
3316 // If true, this is an explicit interface implementation
3318 public readonly bool IsExplicitImpl;
3320 protected bool is_external_implementation;
3323 // The interface type we are explicitly implementing
3325 public TypeSpec InterfaceType;
3328 // The method we're overriding if this is an override method.
3330 protected MethodSpec base_method;
3332 readonly Modifiers explicit_mod_flags;
3333 public MethodAttributes flags;
3335 protected InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
3336 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
3338 IsInterface = parent.Kind == MemberKind.Interface;
3339 IsExplicitImpl = (MemberName.ExplicitInterface != null);
3340 explicit_mod_flags = mod;
3343 public abstract Variance ExpectedMemberTypeVariance { get; }
3345 protected override bool CheckBase ()
3347 if (!base.CheckBase ())
3350 if ((caching_flags & Flags.MethodOverloadsExist) != 0)
3351 CheckForDuplications ();
3356 // For System.Object only
3357 if (Parent.BaseType == null)
3360 MemberSpec candidate;
3361 bool overrides = false;
3362 var base_member = FindBaseMember (out candidate, ref overrides);
3364 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3365 if (base_member == null) {
3366 if (candidate == null) {
3367 if (this is Method && ((Method)this).ParameterInfo.IsEmpty && MemberName.Name == Destructor.MetadataName && MemberName.Arity == 0) {
3368 Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
3369 "object.Finalize()");
3371 Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3372 GetSignatureForError (), SimpleName.GetMemberType (this));
3375 Report.SymbolRelatedToPreviousError (candidate);
3377 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event",
3378 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3379 else if (this is PropertyBase)
3380 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property",
3381 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3383 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method",
3384 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3391 // Handles ambiguous overrides
3393 if (candidate != null) {
3394 Report.SymbolRelatedToPreviousError (candidate);
3395 Report.SymbolRelatedToPreviousError (base_member);
3397 // Get member definition for error reporting
3398 var m1 = MemberCache.GetMember (base_member.DeclaringType.GetDefinition (), base_member);
3399 var m2 = MemberCache.GetMember (candidate.DeclaringType.GetDefinition (), candidate);
3401 Report.Error (462, Location,
3402 "`{0}' cannot override inherited members `{1}' and `{2}' because they have the same signature when used in type `{3}'",
3403 GetSignatureForError (), m1.GetSignatureForError (), m2.GetSignatureForError (), Parent.GetSignatureForError ());
3406 if (!CheckOverrideAgainstBase (base_member))
3409 ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
3411 if (OptAttributes == null || !OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3412 Report.SymbolRelatedToPreviousError (base_member);
3413 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3414 GetSignatureForError (), base_member.GetSignatureForError ());
3417 if (OptAttributes != null && OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3418 Report.SymbolRelatedToPreviousError (base_member);
3419 Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3420 GetSignatureForError (), base_member.GetSignatureForError ());
3424 base_method = base_member as MethodSpec;
3428 if (base_member == null && candidate != null && (!(candidate is IParametersMember) || !(this is IParametersMember)))
3429 base_member = candidate;
3431 if (base_member == null) {
3432 if ((ModFlags & Modifiers.NEW) != 0) {
3433 if (base_member == null) {
3434 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
3435 GetSignatureForError ());
3439 if ((ModFlags & Modifiers.NEW) == 0) {
3440 ModFlags |= Modifiers.NEW;
3441 if (!IsCompilerGenerated) {
3442 Report.SymbolRelatedToPreviousError (base_member);
3443 if ((base_member.Kind & MemberKind.NestedMask) == 0 && !IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
3444 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",
3445 GetSignatureForError (), base_member.GetSignatureForError ());
3447 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3448 GetSignatureForError (), base_member.GetSignatureForError ());
3453 if (!IsInterface && base_member.IsAbstract && !overrides && !IsStatic) {
3454 switch (base_member.Kind) {
3455 case MemberKind.Event:
3456 case MemberKind.Indexer:
3457 case MemberKind.Method:
3458 case MemberKind.Property:
3459 Report.SymbolRelatedToPreviousError (base_member);
3460 Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3461 GetSignatureForError (), base_member.GetSignatureForError ());
3470 protected virtual bool CheckForDuplications ()
3472 return Parent.MemberCache.CheckExistingMembersOverloads (this, ParametersCompiled.EmptyReadOnlyParameters);
3476 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3477 // that have been defined.
3479 protected virtual bool CheckOverrideAgainstBase (MemberSpec base_member)
3483 if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0) {
3484 Report.SymbolRelatedToPreviousError (base_member);
3485 Report.Error (506, Location,
3486 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3487 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3491 // Now we check that the overriden method is not final
3492 if ((base_member.Modifiers & Modifiers.SEALED) != 0) {
3493 Report.SymbolRelatedToPreviousError (base_member);
3494 Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3495 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3499 var base_member_type = ((IInterfaceMemberSpec) base_member).MemberType;
3500 if (!TypeSpecComparer.Override.IsEqual (MemberType, base_member_type)) {
3501 Report.SymbolRelatedToPreviousError (base_member);
3502 if (this is PropertyBasedMember) {
3503 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
3504 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3506 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3507 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3515 protected static bool CheckAccessModifiers (MemberCore this_member, MemberSpec base_member)
3517 var thisp = this_member.ModFlags & Modifiers.AccessibilityMask;
3518 var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask;
3520 if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
3522 // It must be at least "protected"
3524 if ((thisp & Modifiers.PROTECTED) == 0) {
3529 // when overriding protected internal, the method can be declared
3530 // protected internal only within the same assembly or assembly
3531 // which has InternalsVisibleTo
3533 if ((thisp & Modifiers.INTERNAL) != 0) {
3534 return base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly);
3538 // protected overriding protected internal inside same assembly
3539 // requires internal modifier as well
3541 if (base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly)) {
3548 return thisp == base_classp;
3551 public override bool Define ()
3554 ModFlags = Modifiers.PUBLIC | Modifiers.ABSTRACT |
3555 Modifiers.VIRTUAL | (ModFlags & (Modifiers.UNSAFE | Modifiers.NEW));
3557 flags = MethodAttributes.Public |
3558 MethodAttributes.Abstract |
3559 MethodAttributes.HideBySig |
3560 MethodAttributes.NewSlot |
3561 MethodAttributes.Virtual;
3563 Parent.PartialContainer.MethodModifiersValid (this);
3565 flags = ModifiersExtensions.MethodAttr (ModFlags);
3568 if (IsExplicitImpl) {
3569 InterfaceType = MemberName.ExplicitInterface.ResolveAsType (Parent);
3570 if (InterfaceType == null)
3573 if ((ModFlags & Modifiers.PARTIAL) != 0) {
3574 Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
3575 GetSignatureForError ());
3578 if (!InterfaceType.IsInterface) {
3579 Report.SymbolRelatedToPreviousError (InterfaceType);
3580 Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface",
3581 InterfaceType.GetSignatureForError ());
3583 Parent.PartialContainer.VerifyImplements (this);
3586 Modifiers allowed_explicit = Modifiers.AllowedExplicitImplFlags;
3588 allowed_explicit |= Modifiers.ASYNC;
3590 ModifiersExtensions.Check (allowed_explicit, explicit_mod_flags, 0, Location, Report);
3593 return base.Define ();
3596 protected bool DefineParameters (ParametersCompiled parameters)
3598 if (!parameters.Resolve (this))
3602 for (int i = 0; i < parameters.Count; ++i) {
3603 Parameter p = parameters [i];
3605 if (p.HasDefaultValue && (IsExplicitImpl || this is Operator || (this is Indexer && parameters.Count == 1)))
3606 p.Warning_UselessOptionalParameter (Report);
3608 if (p.CheckAccessibility (this))
3611 TypeSpec t = parameters.Types [i];
3612 Report.SymbolRelatedToPreviousError (t);
3613 if (this is Indexer)
3614 Report.Error (55, Location,
3615 "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3616 t.GetSignatureForError (), GetSignatureForError ());
3617 else if (this is Operator)
3618 Report.Error (57, Location,
3619 "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3620 t.GetSignatureForError (), GetSignatureForError ());
3622 Report.Error (51, Location,
3623 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3624 t.GetSignatureForError (), GetSignatureForError ());
3630 protected override void DoMemberTypeDependentChecks ()
3632 base.DoMemberTypeDependentChecks ();
3634 VarianceDecl.CheckTypeVariance (MemberType, ExpectedMemberTypeVariance, this);
3637 public override void Emit()
3639 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3640 // We are more strict than csc and report this as an error because SRE does not allow emit that
3641 if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) {
3642 if (this is Constructor) {
3643 Report.Warning (824, 1, Location,
3644 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3646 Report.Warning (626, 1, Location,
3647 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3648 GetSignatureForError ());
3655 public override bool EnableOverloadChecks (MemberCore overload)
3658 // Two members can differ in their explicit interface
3659 // type parameter only
3661 InterfaceMemberBase imb = overload as InterfaceMemberBase;
3662 if (imb != null && imb.IsExplicitImpl) {
3663 if (IsExplicitImpl) {
3664 caching_flags |= Flags.MethodOverloadsExist;
3669 return IsExplicitImpl;
3672 protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member)
3674 var base_modifiers = base_member.Modifiers;
3676 // Remove internal modifier from types which are not internally accessible
3677 if ((base_modifiers & Modifiers.AccessibilityMask) == (Modifiers.PROTECTED | Modifiers.INTERNAL) &&
3678 !base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly))
3679 base_modifiers = Modifiers.PROTECTED;
3681 Report.SymbolRelatedToPreviousError (base_member);
3682 Report.Error (507, member.Location,
3683 "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3684 member.GetSignatureForError (),
3685 ModifiersExtensions.AccessibilityName (base_modifiers),
3686 base_member.GetSignatureForError ());
3689 protected void Error_StaticReturnType ()
3691 Report.Error (722, Location,
3692 "`{0}': static types cannot be used as return types",
3693 MemberType.GetSignatureForError ());
3697 /// Gets base method and its return type
3699 protected virtual MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
3701 return MemberCache.FindBaseMember (this, out bestCandidate, ref overrides);
3705 // The "short" name of this property / indexer / event. This is the
3706 // name without the explicit interface.
3708 public string ShortName {
3709 get { return MemberName.Name; }
3713 // Returns full metadata method name
3715 public string GetFullName (MemberName name)
3717 return GetFullName (name.Name);
3720 public string GetFullName (string name)
3722 if (!IsExplicitImpl)
3726 // When dealing with explicit members a full interface type
3727 // name is added to member name to avoid possible name conflicts
3729 // We use CSharpName which gets us full name with benefit of
3730 // replacing predefined names which saves some space and name
3733 return InterfaceType.GetSignatureForError () + "." + name;
3736 public override string GetSignatureForDocumentation ()
3739 return Parent.GetSignatureForDocumentation () + "." + InterfaceType.GetSignatureForDocumentation (true) + "#" + ShortName;
3741 return Parent.GetSignatureForDocumentation () + "." + ShortName;
3744 public override bool IsUsed
3746 get { return IsExplicitImpl || base.IsUsed; }
3749 public override void SetConstraints (List<Constraints> constraints_list)
3751 if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
3752 Report.Error (460, Location,
3753 "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
3754 GetSignatureForError ());
3757 base.SetConstraints (constraints_list);
3761 public abstract class MemberBase : MemberCore
3763 protected FullNamedExpression type_expr;
3764 protected TypeSpec member_type;
3765 public new TypeDefinition Parent;
3767 protected MemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
3768 : base (parent, name, attrs)
3770 this.Parent = parent;
3771 this.type_expr = type;
3773 if (name != MemberName.Null)
3774 ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
3779 public TypeSpec MemberType {
3785 public FullNamedExpression TypeExpression {
3797 // Main member define entry
3799 public override bool Define ()
3801 DoMemberTypeIndependentChecks ();
3804 // Returns false only when type resolution failed
3806 if (!ResolveMemberType ())
3809 DoMemberTypeDependentChecks ();
3814 // Any type_name independent checks
3816 protected virtual void DoMemberTypeIndependentChecks ()
3818 if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
3819 (ModFlags & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
3820 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
3821 GetSignatureForError (), Parent.GetSignatureForError ());
3826 // Any type_name dependent checks
3828 protected virtual void DoMemberTypeDependentChecks ()
3830 // verify accessibility
3831 if (!IsAccessibleAs (MemberType)) {
3832 Report.SymbolRelatedToPreviousError (MemberType);
3833 if (this is Property)
3834 Report.Error (53, Location,
3835 "Inconsistent accessibility: property type `" +
3836 MemberType.GetSignatureForError () + "' is less " +
3837 "accessible than property `" + GetSignatureForError () + "'");
3838 else if (this is Indexer)
3839 Report.Error (54, Location,
3840 "Inconsistent accessibility: indexer return type `" +
3841 MemberType.GetSignatureForError () + "' is less " +
3842 "accessible than indexer `" + GetSignatureForError () + "'");
3843 else if (this is MethodCore) {
3844 if (this is Operator)
3845 Report.Error (56, Location,
3846 "Inconsistent accessibility: return type `" +
3847 MemberType.GetSignatureForError () + "' is less " +
3848 "accessible than operator `" + GetSignatureForError () + "'");
3850 Report.Error (50, Location,
3851 "Inconsistent accessibility: return type `" +
3852 MemberType.GetSignatureForError () + "' is less " +
3853 "accessible than method `" + GetSignatureForError () + "'");
3854 } else if (this is Event) {
3855 Report.Error (7025, Location,
3856 "Inconsistent accessibility: event type `{0}' is less accessible than event `{1}'",
3857 MemberType.GetSignatureForError (), GetSignatureForError ());
3859 Report.Error (52, Location,
3860 "Inconsistent accessibility: field type `" +
3861 MemberType.GetSignatureForError () + "' is less " +
3862 "accessible than field `" + GetSignatureForError () + "'");
3867 protected void IsTypePermitted ()
3869 if (MemberType.IsSpecialRuntimeType) {
3870 if (Parent is StateMachine) {
3871 Report.Error (4012, Location,
3872 "Parameters or local variables of type `{0}' cannot be declared in async methods or iterators",
3873 MemberType.GetSignatureForError ());
3874 } else if (Parent is HoistedStoreyClass) {
3875 Report.Error (4013, Location,
3876 "Local variables of type `{0}' cannot be used inside anonymous methods, lambda expressions or query expressions",
3877 MemberType.GetSignatureForError ());
3879 Report.Error (610, Location,
3880 "Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ());
3885 protected virtual bool CheckBase ()
3887 CheckProtectedModifier ();
3892 public override string GetSignatureForDocumentation ()
3894 return Parent.GetSignatureForDocumentation () + "." + MemberName.Basename;
3897 public virtual void PrepareEmit ()
3899 if (member_type != null && type_expr != null)
3900 member_type.CheckObsoleteness (this, type_expr.Location);
3903 protected virtual bool ResolveMemberType ()
3905 if (member_type != null)
3906 throw new InternalErrorException ("Multi-resolve");
3908 member_type = type_expr.ResolveAsType (this);
3909 return member_type != null;