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 local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
1447 tparams.Add (local_tp);
1449 targs.Add (new SimpleName (tp.Name, Location));
1450 targs.Arguments[i] = local_tp.Type;
1453 member_name = new MemberName (name, tparams, Location);
1456 // Mutate any method type parameters from original
1457 // to newly created hoisted version
1459 var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
1460 return_type = mutator.Mutate (return_type);
1461 local_param_types = mutator.Mutate (local_param_types);
1463 member_name = new MemberName (name);
1466 var base_parameters = new Parameter[method.Parameters.Count];
1467 for (int i = 0; i < base_parameters.Length; ++i) {
1468 var base_param = method.Parameters.FixedParameters[i];
1469 base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
1470 base_param.Name, base_param.ModFlags, null, Location);
1471 base_parameters[i].Resolve (this, i);
1474 var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
1475 if (method.Parameters.HasArglist) {
1476 cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
1477 cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
1480 // Compiler generated proxy
1481 proxy_method = new Method (this, new TypeExpression (return_type, Location),
1482 Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
1483 member_name, cloned_params, null);
1485 var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
1486 IsCompilerGenerated = true
1489 var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
1490 mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
1492 mg.SetTypeArguments (rc, targs);
1494 // Get all the method parameters and pass them as arguments
1495 var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
1496 Statement statement;
1497 if (method.ReturnType.Kind == MemberKind.Void)
1498 statement = new StatementExpression (real_base_call);
1500 statement = new Return (real_base_call, Location);
1502 block.AddStatement (statement);
1503 proxy_method.Block = block;
1505 members.Add (proxy_method);
1506 proxy_method.Define ();
1507 proxy_method.PrepareEmit ();
1509 hoisted_base_call_proxies.Add (method, proxy_method);
1512 return proxy_method.Spec;
1515 protected bool DefineBaseTypes ()
1517 if (IsPartialPart && Kind == MemberKind.Class)
1520 return DoDefineBaseType ();
1523 bool DoDefineBaseType ()
1525 iface_exprs = ResolveBaseTypes (out base_type_expr);
1528 if (IsPartialPart) {
1529 set_base_type = false;
1531 if (base_type_expr != null) {
1532 if (PartialContainer.base_type_expr != null && PartialContainer.base_type != base_type) {
1533 Report.SymbolRelatedToPreviousError (base_type_expr.Location, "");
1534 Report.Error (263, Location,
1535 "Partial declarations of `{0}' must not specify different base classes",
1536 GetSignatureForError ());
1538 PartialContainer.base_type_expr = base_type_expr;
1539 PartialContainer.base_type = base_type;
1540 set_base_type = true;
1544 if (iface_exprs != null) {
1545 if (PartialContainer.iface_exprs == null)
1546 PartialContainer.iface_exprs = iface_exprs;
1548 var ifaces = new List<TypeSpec> (PartialContainer.iface_exprs);
1549 foreach (var iface_partial in iface_exprs) {
1550 if (ifaces.Contains (iface_partial))
1553 ifaces.Add (iface_partial);
1556 PartialContainer.iface_exprs = ifaces.ToArray ();
1560 PartialContainer.members.AddRange (members);
1561 if (containers != null) {
1562 if (PartialContainer.containers == null)
1563 PartialContainer.containers = new List<TypeContainer> ();
1565 PartialContainer.containers.AddRange (containers);
1568 if (PrimaryConstructorParameters != null) {
1569 if (PartialContainer.PrimaryConstructorParameters != null) {
1570 Report.Error (8036, Location, "Only one part of a partial type can declare primary constructor parameters");
1572 PartialContainer.PrimaryConstructorParameters = PrimaryConstructorParameters;
1576 members_defined = members_defined_ok = true;
1577 caching_flags |= Flags.CloseTypeCreated;
1579 set_base_type = true;
1582 var cycle = CheckRecursiveDefinition (this);
1583 if (cycle != null) {
1584 Report.SymbolRelatedToPreviousError (cycle);
1585 if (this is Interface) {
1586 Report.Error (529, Location,
1587 "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
1588 GetSignatureForError (), cycle.GetSignatureForError ());
1591 PartialContainer.iface_exprs = null;
1593 Report.Error (146, Location,
1594 "Circular base class dependency involving `{0}' and `{1}'",
1595 GetSignatureForError (), cycle.GetSignatureForError ());
1598 PartialContainer.base_type = null;
1602 if (iface_exprs != null) {
1603 if (!PrimaryConstructorBaseArgumentsStart.IsNull) {
1604 Report.Error (8049, PrimaryConstructorBaseArgumentsStart, "Implemented interfaces cannot have arguments");
1607 foreach (var iface_type in iface_exprs) {
1608 // Prevents a crash, the interface might not have been resolved: 442144
1609 if (iface_type == null)
1612 if (!spec.AddInterfaceDefined (iface_type))
1615 TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
1619 if (Kind == MemberKind.Interface) {
1620 spec.BaseType = Compiler.BuiltinTypes.Object;
1624 if (set_base_type) {
1629 // Base type of partial container has to be resolved before we
1630 // resolve any nested types of the container. We need to know
1631 // partial parts because the base type can be specified in file
1632 // defined after current container
1634 if (class_partial_parts != null) {
1635 foreach (var pp in class_partial_parts) {
1636 if (pp.PrimaryConstructorBaseArguments != null)
1637 PrimaryConstructorBaseArguments = pp.PrimaryConstructorBaseArguments;
1639 pp.DoDefineBaseType ();
1649 if (base_type == null) {
1650 TypeBuilder.SetParent (null);
1654 if (spec.BaseType == base_type)
1657 spec.BaseType = base_type;
1660 spec.UpdateInflatedInstancesBaseType ();
1662 // Set base type after type creation
1663 TypeBuilder.SetParent (base_type.GetMetaInfo ());
1666 public override void ExpandBaseInterfaces ()
1668 DoResolveTypeParameters ();
1671 DoExpandBaseInterfaces ();
1673 base.ExpandBaseInterfaces ();
1676 public void DoExpandBaseInterfaces ()
1678 if ((caching_flags & Flags.InterfacesExpanded) != 0)
1681 caching_flags |= Flags.InterfacesExpanded;
1684 // Expand base interfaces. It cannot be done earlier because all partial
1685 // interface parts need to be defined before the type they are used from
1687 if (iface_exprs != null) {
1688 foreach (var iface in iface_exprs) {
1692 var td = iface.MemberDefinition as TypeDefinition;
1694 td.DoExpandBaseInterfaces ();
1696 if (iface.Interfaces == null)
1699 foreach (var biface in iface.Interfaces) {
1700 if (spec.AddInterfaceDefined (biface)) {
1701 TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ());
1708 // Include all base type interfaces too, see ImportTypeBase for details
1710 if (base_type != null) {
1711 var td = base_type.MemberDefinition as TypeDefinition;
1713 td.DoExpandBaseInterfaces ();
1716 // Simply use base interfaces only, they are all expanded which makes
1717 // it easy to handle generic type argument propagation with single
1720 // interface IA<T> : IB<T>
1721 // interface IB<U> : IC<U>
1724 if (base_type.Interfaces != null) {
1725 foreach (var iface in base_type.Interfaces) {
1726 spec.AddInterfaceDefined (iface);
1732 public override void PrepareEmit ()
1734 if ((caching_flags & Flags.CloseTypeCreated) != 0)
1737 foreach (var member in members) {
1738 var pbm = member as MemberBase;
1743 base.PrepareEmit ();
1747 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1749 public override bool CreateContainer ()
1751 if (TypeBuilder != null)
1757 if (IsPartialPart) {
1758 spec = PartialContainer.spec;
1759 TypeBuilder = PartialContainer.TypeBuilder;
1760 all_tp_builders = PartialContainer.all_tp_builders;
1761 all_type_parameters = PartialContainer.all_type_parameters;
1763 if (!CreateTypeBuilder ()) {
1769 return base.CreateContainer ();
1772 protected override void DoDefineContainer ()
1778 // Replaces normal spec with predefined one when compiling corlib
1779 // and this type container defines predefined type
1781 public void SetPredefinedSpec (BuiltinTypeSpec spec)
1783 // When compiling build-in types we start with two
1784 // version of same type. One is of BuiltinTypeSpec and
1785 // second one is ordinary TypeSpec. The unification
1786 // happens at later stage when we know which type
1787 // really matches the builtin type signature. However
1788 // that means TypeSpec create during CreateType of this
1789 // type has to be replaced with builtin one
1791 spec.SetMetaInfo (TypeBuilder);
1792 spec.MemberCache = this.spec.MemberCache;
1793 spec.DeclaringType = this.spec.DeclaringType;
1796 current_type = null;
1797 if (class_partial_parts != null) {
1798 foreach (var part in class_partial_parts)
1803 public override void RemoveContainer (TypeContainer cont)
1805 base.RemoveContainer (cont);
1806 Members.Remove (cont);
1807 Cache.Remove (cont.MemberName.Basename);
1810 protected virtual bool DoResolveTypeParameters ()
1812 var tparams = MemberName.TypeParameters;
1813 if (tparams == null)
1816 var base_context = new BaseContext (this);
1817 for (int i = 0; i < tparams.Count; ++i) {
1818 var tp = tparams[i];
1820 if (!tp.ResolveConstraints (base_context)) {
1825 if (IsPartialPart) {
1826 var pc_tp = PartialContainer.CurrentTypeParameters [i];
1828 tp.Create (spec, this);
1831 if (tp.OptAttributes != null) {
1832 if (pc_tp.OptAttributes == null)
1833 pc_tp.OptAttributes = tp.OptAttributes;
1835 pc_tp.OptAttributes.Attrs.AddRange (tp.OptAttributes.Attrs);
1840 if (IsPartialPart) {
1841 PartialContainer.CurrentTypeParameters.UpdateConstraints (this);
1847 TypeSpec CheckRecursiveDefinition (TypeDefinition tc)
1849 if (InTransit != null)
1854 if (base_type != null) {
1855 var ptc = base_type.MemberDefinition as TypeDefinition;
1856 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1860 if (iface_exprs != null && this is Interface) {
1861 foreach (var iface in iface_exprs) {
1862 // the interface might not have been resolved, prevents a crash, see #442144
1865 var ptc = iface.MemberDefinition as Interface;
1866 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1871 if (!IsTopLevel && Parent.PartialContainer.CheckRecursiveDefinition (this) != null)
1879 /// Populates our TypeBuilder with fields and methods
1881 public sealed override bool Define ()
1883 if (members_defined)
1884 return members_defined_ok;
1886 members_defined_ok = DoDefineMembers ();
1887 members_defined = true;
1891 return members_defined_ok;
1894 protected virtual bool DoDefineMembers ()
1896 Debug.Assert (!IsPartialPart);
1898 if (iface_exprs != null) {
1899 foreach (var iface_type in iface_exprs) {
1900 if (iface_type == null)
1903 // Ensure the base is always setup
1904 var compiled_iface = iface_type.MemberDefinition as Interface;
1905 if (compiled_iface != null)
1906 compiled_iface.Define ();
1908 iface_type.CheckObsoleteness (this, Location);
1910 if (iface_type.Arity > 0) {
1911 // TODO: passing `this' is wrong, should be base type iface instead
1912 VarianceDecl.CheckTypeVariance (iface_type, Variance.Covariant, this);
1914 if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) {
1915 Report.Error (1966, Location,
1916 "`{0}': cannot implement a dynamic interface `{1}'",
1917 GetSignatureForError (), iface_type.GetSignatureForError ());
1922 if (iface_type.IsGenericOrParentIsGeneric) {
1923 foreach (var prev_iface in iface_exprs) {
1924 if (prev_iface == iface_type || prev_iface == null)
1927 if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
1930 Report.Error (695, Location,
1931 "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
1932 GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
1937 if (Kind == MemberKind.Interface) {
1938 foreach (var iface in spec.Interfaces) {
1939 MemberCache.AddInterface (iface);
1944 if (base_type != null) {
1946 // Run checks skipped during DefineType (e.g FullNamedExpression::ResolveAsType)
1948 if (base_type_expr != null) {
1949 base_type.CheckObsoleteness (this, base_type_expr.Location);
1951 if (IsGenericOrParentIsGeneric && base_type.IsAttribute) {
1952 Report.Error (698, base_type_expr.Location,
1953 "A generic type cannot derive from `{0}' because it is an attribute class",
1954 base_type.GetSignatureForError ());
1958 var baseContainer = base_type.MemberDefinition as ClassOrStruct;
1959 if (baseContainer != null) {
1960 baseContainer.Define ();
1963 // It can trigger define of this type (for generic types only)
1965 if (HasMembersDefined)
1970 if (Kind == MemberKind.Struct || Kind == MemberKind.Class) {
1971 pending = PendingImplementation.GetPendingImplementations (this);
1974 var count = members.Count;
1975 for (int i = 0; i < count; ++i) {
1976 var mc = members[i] as InterfaceMemberBase;
1977 if (mc == null || !mc.IsExplicitImpl)
1982 } catch (Exception e) {
1983 throw new InternalErrorException (mc, e);
1987 for (int i = 0; i < count; ++i) {
1988 var mc = members[i] as InterfaceMemberBase;
1989 if (mc != null && mc.IsExplicitImpl)
1992 if (members[i] is TypeContainer)
1996 members[i].Define ();
1997 } catch (Exception e) {
1998 throw new InternalErrorException (members[i], e);
2003 CheckPairedOperators ();
2006 ComputeIndexerName();
2008 if (HasEquals && !HasGetHashCode) {
2009 Report.Warning (659, 3, Location,
2010 "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ());
2013 if (Kind == MemberKind.Interface && iface_exprs != null) {
2014 MemberCache.RemoveHiddenMembers (spec);
2020 void ComputeIndexerName ()
2022 var indexers = MemberCache.FindMembers (spec, MemberCache.IndexerNameAlias, true);
2023 if (indexers == null)
2026 string class_indexer_name = null;
2029 // Check normal indexers for consistent name, explicit interface implementation
2030 // indexers are ignored
2032 foreach (var indexer in indexers) {
2034 // FindMembers can return unfiltered full hierarchy names
2036 if (indexer.DeclaringType != spec)
2039 has_normal_indexers = true;
2041 if (class_indexer_name == null) {
2042 indexer_name = class_indexer_name = indexer.Name;
2046 if (indexer.Name != class_indexer_name)
2047 Report.Error (668, ((Indexer)indexer.MemberDefinition).Location,
2048 "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
2052 void EmitIndexerName ()
2054 if (!has_normal_indexers)
2057 var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
2061 var encoder = new AttributeEncoder ();
2062 encoder.Encode (GetAttributeDefaultMember ());
2063 encoder.EncodeEmptyNamedArguments ();
2065 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
2068 public override void VerifyMembers ()
2071 // Check for internal or private fields that were never assigned
2073 if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) {
2074 bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
2075 foreach (var member in members) {
2076 if (member is Event) {
2078 // An event can be assigned from same class only, report
2079 // this warning for all accessibility modes
2081 if (!member.IsUsed && !PartialContainer.HasStructLayout)
2082 Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ());
2087 if ((member.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
2088 if (is_type_exposed)
2091 member.SetIsUsed ();
2094 var f = member as Field;
2098 if (!member.IsUsed) {
2099 if (!PartialContainer.HasStructLayout) {
2100 if ((member.caching_flags & Flags.IsAssigned) == 0) {
2101 Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ());
2103 Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used",
2104 member.GetSignatureForError ());
2111 if ((f.caching_flags & Flags.IsAssigned) != 0)
2115 // Only report 649 on level 4
2117 if (Compiler.Settings.WarningLevel < 4)
2121 // Don't be pedantic when type requires specific layout
2123 if (f.OptAttributes != null || PartialContainer.HasStructLayout)
2126 Constant c = New.Constantify (f.MemberType, f.Location);
2129 value = c.GetValueAsLiteral ();
2130 } else if (TypeSpec.IsReferenceType (f.MemberType)) {
2137 value = " `" + value + "'";
2139 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
2140 f.GetSignatureForError (), value);
2144 base.VerifyMembers ();
2147 public override void Emit ()
2149 if (OptAttributes != null)
2150 OptAttributes.Emit ();
2152 if (!IsCompilerGenerated) {
2154 MemberSpec candidate;
2155 bool overrides = false;
2156 var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
2157 if (conflict_symbol == null && candidate == null) {
2158 if ((ModFlags & Modifiers.NEW) != 0)
2159 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
2160 GetSignatureForError ());
2162 if ((ModFlags & Modifiers.NEW) == 0) {
2163 if (candidate == null)
2164 candidate = conflict_symbol;
2166 Report.SymbolRelatedToPreviousError (candidate);
2167 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
2168 GetSignatureForError (), candidate.GetSignatureForError ());
2173 // Run constraints check on all possible generic types
2174 if (base_type != null && base_type_expr != null) {
2175 ConstraintChecker.Check (this, base_type, base_type_expr.Location);
2178 if (iface_exprs != null) {
2179 foreach (var iface_type in iface_exprs) {
2180 if (iface_type == null)
2183 ConstraintChecker.Check (this, iface_type, Location); // TODO: Location is wrong
2188 if (all_tp_builders != null) {
2189 int current_starts_index = CurrentTypeParametersStartIndex;
2190 for (int i = 0; i < all_tp_builders.Length; i++) {
2191 if (i < current_starts_index) {
2192 all_type_parameters[i].EmitConstraints (all_tp_builders [i]);
2194 var tp = CurrentTypeParameters [i - current_starts_index];
2195 tp.CheckGenericConstraints (!IsObsolete);
2201 if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2202 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (TypeBuilder);
2205 if ((TypeBuilder.Attributes & TypeAttributes.StringFormatMask) == 0 && Module.HasDefaultCharSet)
2206 TypeBuilder.__SetAttributes (TypeBuilder.Attributes | Module.DefaultCharSetType);
2211 for (int i = 0; i < members.Count; i++) {
2213 if ((m.caching_flags & Flags.CloseTypeCreated) != 0)
2220 CheckAttributeClsCompliance ();
2222 if (pending != null)
2223 pending.VerifyPendingMethods ();
2227 void CheckAttributeClsCompliance ()
2229 if (!spec.IsAttribute || !IsExposedFromAssembly () || !Compiler.Settings.VerifyClsCompliance || !IsClsComplianceRequired ())
2232 foreach (var m in members) {
2233 var c = m as Constructor;
2237 if (c.HasCompliantArgs)
2241 Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2244 public sealed override void EmitContainer ()
2246 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2252 public override void CloseContainer ()
2254 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2257 // Close base type container first to avoid TypeLoadException
2258 if (spec.BaseType != null) {
2259 var btype = spec.BaseType.MemberDefinition as TypeContainer;
2260 if (btype != null) {
2261 btype.CloseContainer ();
2263 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2269 caching_flags |= Flags.CloseTypeCreated;
2270 TypeBuilder.CreateType ();
2271 } catch (TypeLoadException) {
2273 // This is fine, the code still created the type
2275 } catch (Exception e) {
2276 throw new InternalErrorException (this, e);
2279 base.CloseContainer ();
2282 initialized_fields = null;
2283 initialized_static_fields = null;
2285 OptAttributes = null;
2289 // Performs the validation on a Method's modifiers (properties have
2290 // the same properties).
2292 // TODO: Why is it not done at parse stage, move to Modifiers::Check
2294 public bool MethodModifiersValid (MemberCore mc)
2296 const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2297 const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2299 var flags = mc.ModFlags;
2302 // At most one of static, virtual or override
2304 if ((flags & Modifiers.STATIC) != 0){
2305 if ((flags & vao) != 0){
2306 Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2307 mc.GetSignatureForError ());
2312 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2313 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2314 mc.GetSignatureForError ());
2319 // If the declaration includes the abstract modifier, then the
2320 // declaration does not include static, virtual or extern
2322 if ((flags & Modifiers.ABSTRACT) != 0){
2323 if ((flags & Modifiers.EXTERN) != 0){
2325 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2329 if ((flags & Modifiers.SEALED) != 0) {
2330 Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2334 if ((flags & Modifiers.VIRTUAL) != 0){
2335 Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2339 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2340 Report.SymbolRelatedToPreviousError (this);
2341 Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2342 mc.GetSignatureForError (), GetSignatureForError ());
2347 if ((flags & Modifiers.PRIVATE) != 0){
2348 if ((flags & vao) != 0){
2349 Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2354 if ((flags & Modifiers.SEALED) != 0){
2355 if ((flags & Modifiers.OVERRIDE) == 0){
2356 Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2364 protected override bool VerifyClsCompliance ()
2366 if (!base.VerifyClsCompliance ())
2369 // Check all container names for user classes
2370 if (Kind != MemberKind.Delegate)
2371 MemberCache.VerifyClsCompliance (Definition, Report);
2373 if (BaseType != null && !BaseType.IsCLSCompliant ()) {
2374 Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant",
2375 GetSignatureForError (), BaseType.GetSignatureForError ());
2381 /// Performs checks for an explicit interface implementation. First it
2382 /// checks whether the `interface_type' is a base inteface implementation.
2383 /// Then it checks whether `name' exists in the interface type.
2385 public bool VerifyImplements (InterfaceMemberBase mb)
2387 var ifaces = PartialContainer.Interfaces;
2388 if (ifaces != null) {
2389 foreach (TypeSpec t in ifaces){
2390 if (t == mb.InterfaceType || t == null)
2393 var expanded_base = t.Interfaces;
2394 if (expanded_base == null)
2397 foreach (var bt in expanded_base) {
2398 if (bt == mb.InterfaceType)
2404 Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2405 Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2406 mb.GetSignatureForError (), mb.InterfaceType.GetSignatureForError ());
2411 // Used for visiblity checks to tests whether this definition shares
2412 // base type baseType, it does member-definition search
2414 public bool IsBaseTypeDefinition (TypeSpec baseType)
2416 // RootContext check
2417 if (TypeBuilder == null)
2422 if (type.MemberDefinition == baseType.MemberDefinition)
2425 type = type.BaseType;
2426 } while (type != null);
2431 public override bool IsClsComplianceRequired ()
2434 return PartialContainer.IsClsComplianceRequired ();
2436 return base.IsClsComplianceRequired ();
2439 bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
2441 return Module.DeclaringAssembly == assembly;
2444 public virtual bool IsUnmanagedType ()
2449 public void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache)
2451 throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ());
2455 // Public function used to locate types.
2457 // Returns: Type or null if they type can not be found.
2459 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
2461 FullNamedExpression e;
2462 if (arity == 0 && Cache.TryGetValue (name, out e) && mode != LookupMode.IgnoreAccessibility)
2468 var tp = CurrentTypeParameters;
2470 TypeParameter tparam = tp.Find (name);
2472 e = new TypeParameterExpr (tparam, Location.Null);
2477 TypeSpec t = LookupNestedTypeInHierarchy (name, arity);
2479 if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility))
2480 e = new TypeExpression (t, Location.Null);
2482 var errors = Compiler.Report.Errors;
2483 e = Parent.LookupNamespaceOrType (name, arity, mode, loc);
2485 // TODO: LookupNamespaceOrType does more than just lookup. The result
2486 // cannot be cached or the error reporting won't happen
2487 if (errors != Compiler.Report.Errors)
2492 // TODO MemberCache: How to cache arity stuff ?
2493 if (arity == 0 && mode == LookupMode.Normal)
2499 TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
2501 // Has any nested type
2502 // Does not work, because base type can have
2503 //if (PartialContainer.Types == null)
2506 var container = PartialContainer.CurrentType;
2507 return MemberCache.FindNestedType (container, name, arity, false);
2510 public void Mark_HasEquals ()
2512 cached_method |= CachedMethods.Equals;
2515 public void Mark_HasGetHashCode ()
2517 cached_method |= CachedMethods.GetHashCode;
2520 public override void WriteDebugSymbol (MonoSymbolFile file)
2525 foreach (var m in members) {
2526 m.WriteDebugSymbol (file);
2531 /// Method container contains Equals method
2533 public bool HasEquals {
2535 return (cached_method & CachedMethods.Equals) != 0;
2540 /// Method container contains GetHashCode method
2542 public bool HasGetHashCode {
2544 return (cached_method & CachedMethods.GetHashCode) != 0;
2548 public bool HasStaticFieldInitializer {
2550 return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
2554 cached_method |= CachedMethods.HasStaticFieldInitializer;
2556 cached_method &= ~CachedMethods.HasStaticFieldInitializer;
2560 public override string DocCommentHeader {
2561 get { return "T:"; }
2565 public abstract class ClassOrStruct : TypeDefinition
2567 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2569 SecurityType declarative_security;
2570 protected Constructor generated_primary_constructor;
2572 protected ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
2573 : base (parent, name, attrs, kind)
2577 public ToplevelBlock PrimaryConstructorBlock { get; set; }
2579 protected override TypeAttributes TypeAttr {
2581 TypeAttributes ta = base.TypeAttr;
2582 if (!has_static_constructor)
2583 ta |= TypeAttributes.BeforeFieldInit;
2585 if (Kind == MemberKind.Class) {
2586 ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
2588 ta |= StaticClassAttribute;
2590 ta |= TypeAttributes.SequentialLayout;
2597 public override void AddNameToContainer (MemberCore symbol, string name)
2599 if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) {
2600 if (symbol is TypeParameter) {
2601 Report.Error (694, symbol.Location,
2602 "Type parameter `{0}' has same name as containing type, or method",
2603 symbol.GetSignatureForError ());
2607 InterfaceMemberBase imb = symbol as InterfaceMemberBase;
2608 if (imb == null || !imb.IsExplicitImpl) {
2609 Report.SymbolRelatedToPreviousError (this);
2610 Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2611 symbol.GetSignatureForError ());
2616 base.AddNameToContainer (symbol, name);
2619 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2621 if (a.IsValidSecurityAttribute ()) {
2622 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2626 if (a.Type == pa.StructLayout) {
2627 PartialContainer.HasStructLayout = true;
2628 if (a.IsExplicitLayoutKind ())
2629 PartialContainer.HasExplicitLayout = true;
2632 if (a.Type == pa.Dynamic) {
2633 a.Error_MisusedDynamicAttribute ();
2637 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2641 /// Defines the default constructors
2643 protected virtual Constructor DefineDefaultConstructor (bool is_static)
2645 // The default instance constructor is public
2646 // If the class is abstract, the default constructor is protected
2647 // The default static constructor is private
2650 ParametersCompiled parameters = null;
2652 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2653 parameters = ParametersCompiled.EmptyReadOnlyParameters;
2655 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2656 parameters = PrimaryConstructorParameters ?? ParametersCompiled.EmptyReadOnlyParameters;
2659 var c = new Constructor (this, MemberName.Name, mods, null, parameters, Location);
2660 if (Kind == MemberKind.Class)
2661 c.Initializer = new GeneratedBaseInitializer (Location, PrimaryConstructorBaseArguments);
2663 if (PrimaryConstructorParameters != null && !is_static) {
2664 c.IsPrimaryConstructor = true;
2665 c.caching_flags |= Flags.MethodOverloadsExist;
2668 AddConstructor (c, true);
2669 if (PrimaryConstructorBlock == null) {
2670 c.Block = new ToplevelBlock (Compiler, parameters, Location) {
2671 IsCompilerGenerated = true
2674 c.Block = PrimaryConstructorBlock;
2680 protected override bool DoDefineMembers ()
2682 CheckProtectedModifier ();
2684 if (PrimaryConstructorParameters != null) {
2686 foreach (Parameter p in PrimaryConstructorParameters.FixedParameters) {
2687 if (p.Name == MemberName.Name) {
2688 Report.Error (8039, p.Location, "Primary constructor of type `{0}' has parameter of same name as containing type",
2689 GetSignatureForError ());
2692 if (CurrentTypeParameters != null) {
2693 for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
2694 var tp = CurrentTypeParameters [i];
2695 if (p.Name == tp.Name) {
2696 Report.Error (8038, p.Location, "Primary constructor of type `{0}' has parameter of same name as type parameter `{1}'",
2697 GetSignatureForError (), p.GetSignatureForError ());
2704 base.DoDefineMembers ();
2709 public override void PrepareEmit ()
2711 var s = this as Struct;
2712 if (s == null || !s.HasUnmanagedCheckDone) {
2713 for (int i = 0; i < Members.Count; ++i) {
2714 var f = Members [i] as Field;
2715 if (f == null || f.MemberType == null || !f.MemberType.IsPointer)
2718 TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
2722 base.PrepareEmit ();
2725 public override void Emit ()
2727 if (!has_static_constructor && HasStaticFieldInitializer) {
2728 var c = DefineDefaultConstructor (true);
2734 if (declarative_security != null) {
2735 foreach (var de in declarative_security) {
2737 TypeBuilder.__AddDeclarativeSecurity (de);
2739 TypeBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2747 public sealed class Class : ClassOrStruct
2749 const Modifiers AllowedModifiers =
2752 Modifiers.PROTECTED |
2753 Modifiers.INTERNAL |
2755 Modifiers.ABSTRACT |
2760 public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2761 : base (parent, name, attrs, MemberKind.Class)
2763 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2764 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
2765 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2768 public override void Accept (StructuralVisitor visitor)
2770 visitor.Visit (this);
2773 public override void SetBaseTypes (List<FullNamedExpression> baseTypes)
2775 var pmn = MemberName;
2776 if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null)
2777 Report.Error (537, Location,
2778 "The class System.Object cannot have a base class or implement an interface.");
2780 base.SetBaseTypes (baseTypes);
2783 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2785 if (a.Type == pa.AttributeUsage) {
2786 if (!BaseType.IsAttribute && spec.BuiltinType != BuiltinTypeSpec.Type.Attribute) {
2787 Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2791 if (a.Type == pa.Conditional && !BaseType.IsAttribute) {
2792 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2796 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
2797 a.Error_MissingGuidAttribute ();
2801 if (a.Type == pa.Extension) {
2802 a.Error_MisusedExtensionAttribute ();
2806 if (a.Type.IsConditionallyExcluded (this))
2809 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2812 public override AttributeTargets AttributeTargets {
2814 return AttributeTargets.Class;
2818 protected override bool DoDefineMembers ()
2820 if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2821 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2824 if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2825 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2829 if (PrimaryConstructorParameters != null) {
2830 Report.Error (-800, Location, "`{0}': Static classes cannot have primary constructor", GetSignatureForError ());
2831 PrimaryConstructorParameters = null;
2834 foreach (var m in Members) {
2835 if (m is Operator) {
2836 Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2840 if (m is Destructor) {
2841 Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2846 Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2850 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is TypeContainer)
2853 if (m is Constructor) {
2854 Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2858 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2861 if (!PartialContainer.HasInstanceConstructor || PrimaryConstructorParameters != null)
2862 generated_primary_constructor = DefineDefaultConstructor (false);
2865 return base.DoDefineMembers ();
2868 public override void Emit ()
2872 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
2873 Module.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
2875 if (base_type != null && base_type.HasDynamicElement) {
2876 Module.PredefinedAttributes.Dynamic.EmitAttribute (TypeBuilder, base_type, Location);
2880 public override void GetCompletionStartingWith (string prefix, List<string> results)
2882 base.GetCompletionStartingWith (prefix, results);
2885 while (bt != null) {
2886 results.AddRange (MemberCache.GetCompletitionMembers (this, bt, prefix).Where (l => l.IsStatic).Select (l => l.Name));
2891 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
2893 var ifaces = base.ResolveBaseTypes (out base_class);
2895 if (base_class == null) {
2896 if (spec.BuiltinType != BuiltinTypeSpec.Type.Object)
2897 base_type = Compiler.BuiltinTypes.Object;
2899 if (base_type.IsGenericParameter){
2900 Report.Error (689, base_class.Location, "`{0}': Cannot derive from type parameter `{1}'",
2901 GetSignatureForError (), base_type.GetSignatureForError ());
2902 } else if (base_type.IsStatic) {
2903 Report.SymbolRelatedToPreviousError (base_type);
2904 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
2905 GetSignatureForError (), base_type.GetSignatureForError ());
2906 } else if (base_type.IsSealed) {
2907 Report.SymbolRelatedToPreviousError (base_type);
2908 Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
2909 GetSignatureForError (), base_type.GetSignatureForError ());
2910 } else if (PartialContainer.IsStatic && base_type.BuiltinType != BuiltinTypeSpec.Type.Object) {
2911 Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2912 GetSignatureForError (), base_type.GetSignatureForError ());
2915 switch (base_type.BuiltinType) {
2916 case BuiltinTypeSpec.Type.Enum:
2917 case BuiltinTypeSpec.Type.ValueType:
2918 case BuiltinTypeSpec.Type.MulticastDelegate:
2919 case BuiltinTypeSpec.Type.Delegate:
2920 case BuiltinTypeSpec.Type.Array:
2921 if (!(spec is BuiltinTypeSpec)) {
2922 Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
2923 GetSignatureForError (), base_type.GetSignatureForError ());
2925 base_type = Compiler.BuiltinTypes.Object;
2930 if (!IsAccessibleAs (base_type)) {
2931 Report.SymbolRelatedToPreviousError (base_type);
2932 Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
2933 base_type.GetSignatureForError (), GetSignatureForError ());
2937 if (PartialContainer.IsStatic && ifaces != null) {
2938 foreach (var t in ifaces)
2939 Report.SymbolRelatedToPreviousError (t);
2940 Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2946 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2947 /// Valid only for attribute classes.
2948 public override string[] ConditionalConditions ()
2950 if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
2953 caching_flags &= ~Flags.Excluded_Undetected;
2955 if (OptAttributes == null)
2958 Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
2962 string[] conditions = new string[attrs.Length];
2963 for (int i = 0; i < conditions.Length; ++i)
2964 conditions[i] = attrs[i].GetConditionalAttributeValue ();
2966 caching_flags |= Flags.Excluded;
2971 public sealed class Struct : ClassOrStruct
2973 bool is_unmanaged, has_unmanaged_check_done, requires_delayed_unmanagedtype_check;
2977 // Modifiers allowed in a struct declaration
2979 const Modifiers AllowedModifiers =
2982 Modifiers.PROTECTED |
2983 Modifiers.INTERNAL |
2987 public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2988 : base (parent, name, attrs, MemberKind.Struct)
2990 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2991 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
2992 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2995 public override AttributeTargets AttributeTargets {
2997 return AttributeTargets.Struct;
3001 public override void Accept (StructuralVisitor visitor)
3003 visitor.Visit (this);
3006 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
3008 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
3011 // When struct constains fixed fixed and struct layout has explicitly
3012 // set CharSet, its value has to be propagated to compiler generated
3015 if (a.Type == pa.StructLayout) {
3016 var value = a.GetNamedValue ("CharSet");
3020 for (int i = 0; i < Members.Count; ++i) {
3021 FixedField ff = Members [i] as FixedField;
3025 ff.CharSetValue = (CharSet) System.Enum.Parse (typeof (CharSet), value.GetValue ().ToString ());
3030 bool CheckStructCycles ()
3036 foreach (var member in Members) {
3037 var field = member as Field;
3041 TypeSpec ftype = field.Spec.MemberType;
3042 if (!ftype.IsStruct)
3045 if (ftype is BuiltinTypeSpec)
3048 foreach (var targ in ftype.TypeArguments) {
3049 if (!CheckFieldTypeCycle (targ)) {
3050 Report.Error (523, field.Location,
3051 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
3052 field.GetSignatureForError (), ftype.GetSignatureForError ());
3058 // Static fields of exactly same type are allowed
3060 if (field.IsStatic && ftype == CurrentType)
3063 if (!CheckFieldTypeCycle (ftype)) {
3064 Report.Error (523, field.Location,
3065 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
3066 field.GetSignatureForError (), ftype.GetSignatureForError ());
3075 static bool CheckFieldTypeCycle (TypeSpec ts)
3077 var fts = ts.MemberDefinition as Struct;
3081 return fts.CheckStructCycles ();
3084 protected override bool DoDefineMembers ()
3086 var res = base.DoDefineMembers ();
3088 if (PrimaryConstructorParameters != null || (initialized_fields != null && !HasUserDefaultConstructor ())) {
3089 generated_primary_constructor = DefineDefaultConstructor (false);
3090 generated_primary_constructor.Define ();
3096 public override void Emit ()
3098 CheckStructCycles ();
3103 public bool HasUnmanagedCheckDone {
3105 return has_unmanaged_check_done;
3109 bool HasUserDefaultConstructor ()
3111 foreach (var m in PartialContainer.Members) {
3112 var c = m as Constructor;
3116 if (!c.IsStatic && c.ParameterInfo.IsEmpty)
3123 public override bool IsUnmanagedType ()
3125 if (has_unmanaged_check_done)
3126 return is_unmanaged;
3128 if (requires_delayed_unmanagedtype_check)
3131 var parent_def = Parent.PartialContainer;
3132 if (parent_def != null && parent_def.IsGenericOrParentIsGeneric) {
3133 has_unmanaged_check_done = true;
3137 if (first_nonstatic_field != null) {
3138 requires_delayed_unmanagedtype_check = true;
3140 foreach (var member in Members) {
3141 var f = member as Field;
3148 // It can happen when recursive unmanaged types are defined
3149 // struct S { S* s; }
3150 TypeSpec mt = f.MemberType;
3158 has_unmanaged_check_done = true;
3162 has_unmanaged_check_done = true;
3165 is_unmanaged = true;
3169 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
3171 var ifaces = base.ResolveBaseTypes (out base_class);
3172 base_type = Compiler.BuiltinTypes.ValueType;
3180 public sealed class Interface : TypeDefinition {
3183 /// Modifiers allowed in a class declaration
3185 const Modifiers AllowedModifiers =
3188 Modifiers.PROTECTED |
3189 Modifiers.INTERNAL |
3193 public Interface (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
3194 : base (parent, name, attrs, MemberKind.Interface)
3196 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
3198 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
3199 spec = new TypeSpec (Kind, null, this, null, ModFlags);
3204 public override AttributeTargets AttributeTargets {
3206 return AttributeTargets.Interface;
3210 protected override TypeAttributes TypeAttr {
3212 const TypeAttributes DefaultTypeAttributes =
3213 TypeAttributes.AutoLayout |
3214 TypeAttributes.Abstract |
3215 TypeAttributes.Interface;
3217 return base.TypeAttr | DefaultTypeAttributes;
3223 public override void Accept (StructuralVisitor visitor)
3225 visitor.Visit (this);
3228 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
3230 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
3231 a.Error_MissingGuidAttribute ();
3235 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
3238 protected override bool VerifyClsCompliance ()
3240 if (!base.VerifyClsCompliance ())
3243 if (iface_exprs != null) {
3244 foreach (var iface in iface_exprs) {
3245 if (iface.IsCLSCompliant ())
3248 Report.SymbolRelatedToPreviousError (iface);
3249 Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3250 GetSignatureForError (), iface.GetSignatureForError ());
3258 public abstract class InterfaceMemberBase : MemberBase
3261 // Common modifiers allowed in a class declaration
3263 protected const Modifiers AllowedModifiersClass =
3266 Modifiers.PROTECTED |
3267 Modifiers.INTERNAL |
3272 Modifiers.OVERRIDE |
3273 Modifiers.ABSTRACT |
3278 // Common modifiers allowed in a struct declaration
3280 protected const Modifiers AllowedModifiersStruct =
3283 Modifiers.PROTECTED |
3284 Modifiers.INTERNAL |
3287 Modifiers.OVERRIDE |
3292 // Common modifiers allowed in a interface declaration
3294 protected const Modifiers AllowedModifiersInterface =
3299 // Whether this is an interface member.
3301 public bool IsInterface;
3304 // If true, this is an explicit interface implementation
3306 public readonly bool IsExplicitImpl;
3308 protected bool is_external_implementation;
3311 // The interface type we are explicitly implementing
3313 public TypeSpec InterfaceType;
3316 // The method we're overriding if this is an override method.
3318 protected MethodSpec base_method;
3320 readonly Modifiers explicit_mod_flags;
3321 public MethodAttributes flags;
3323 protected InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
3324 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
3326 IsInterface = parent.Kind == MemberKind.Interface;
3327 IsExplicitImpl = (MemberName.ExplicitInterface != null);
3328 explicit_mod_flags = mod;
3331 public abstract Variance ExpectedMemberTypeVariance { get; }
3333 protected override bool CheckBase ()
3335 if (!base.CheckBase ())
3338 if ((caching_flags & Flags.MethodOverloadsExist) != 0)
3339 CheckForDuplications ();
3344 // For System.Object only
3345 if (Parent.BaseType == null)
3348 MemberSpec candidate;
3349 bool overrides = false;
3350 var base_member = FindBaseMember (out candidate, ref overrides);
3352 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3353 if (base_member == null) {
3354 if (candidate == null) {
3355 if (this is Method && ((Method)this).ParameterInfo.IsEmpty && MemberName.Name == Destructor.MetadataName && MemberName.Arity == 0) {
3356 Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
3357 "object.Finalize()");
3359 Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3360 GetSignatureForError (), SimpleName.GetMemberType (this));
3363 Report.SymbolRelatedToPreviousError (candidate);
3365 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event",
3366 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3367 else if (this is PropertyBase)
3368 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property",
3369 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3371 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method",
3372 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3379 // Handles ambiguous overrides
3381 if (candidate != null) {
3382 Report.SymbolRelatedToPreviousError (candidate);
3383 Report.SymbolRelatedToPreviousError (base_member);
3385 // Get member definition for error reporting
3386 var m1 = MemberCache.GetMember (base_member.DeclaringType.GetDefinition (), base_member);
3387 var m2 = MemberCache.GetMember (candidate.DeclaringType.GetDefinition (), candidate);
3389 Report.Error (462, Location,
3390 "`{0}' cannot override inherited members `{1}' and `{2}' because they have the same signature when used in type `{3}'",
3391 GetSignatureForError (), m1.GetSignatureForError (), m2.GetSignatureForError (), Parent.GetSignatureForError ());
3394 if (!CheckOverrideAgainstBase (base_member))
3397 ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
3399 if (OptAttributes == null || !OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3400 Report.SymbolRelatedToPreviousError (base_member);
3401 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3402 GetSignatureForError (), base_member.GetSignatureForError ());
3405 if (OptAttributes != null && OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3406 Report.SymbolRelatedToPreviousError (base_member);
3407 Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3408 GetSignatureForError (), base_member.GetSignatureForError ());
3412 base_method = base_member as MethodSpec;
3416 if (base_member == null && candidate != null && (!(candidate is IParametersMember) || !(this is IParametersMember)))
3417 base_member = candidate;
3419 if (base_member == null) {
3420 if ((ModFlags & Modifiers.NEW) != 0) {
3421 if (base_member == null) {
3422 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
3423 GetSignatureForError ());
3427 if ((ModFlags & Modifiers.NEW) == 0) {
3428 ModFlags |= Modifiers.NEW;
3429 if (!IsCompilerGenerated) {
3430 Report.SymbolRelatedToPreviousError (base_member);
3431 if ((base_member.Kind & MemberKind.NestedMask) == 0 && !IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
3432 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",
3433 GetSignatureForError (), base_member.GetSignatureForError ());
3435 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3436 GetSignatureForError (), base_member.GetSignatureForError ());
3441 if (!IsInterface && base_member.IsAbstract && !overrides && !IsStatic) {
3442 switch (base_member.Kind) {
3443 case MemberKind.Event:
3444 case MemberKind.Indexer:
3445 case MemberKind.Method:
3446 case MemberKind.Property:
3447 Report.SymbolRelatedToPreviousError (base_member);
3448 Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3449 GetSignatureForError (), base_member.GetSignatureForError ());
3458 protected virtual bool CheckForDuplications ()
3460 return Parent.MemberCache.CheckExistingMembersOverloads (this, ParametersCompiled.EmptyReadOnlyParameters);
3464 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3465 // that have been defined.
3467 protected virtual bool CheckOverrideAgainstBase (MemberSpec base_member)
3471 if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0) {
3472 Report.SymbolRelatedToPreviousError (base_member);
3473 Report.Error (506, Location,
3474 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3475 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3479 // Now we check that the overriden method is not final
3480 if ((base_member.Modifiers & Modifiers.SEALED) != 0) {
3481 Report.SymbolRelatedToPreviousError (base_member);
3482 Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3483 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3487 var base_member_type = ((IInterfaceMemberSpec) base_member).MemberType;
3488 if (!TypeSpecComparer.Override.IsEqual (MemberType, base_member_type)) {
3489 Report.SymbolRelatedToPreviousError (base_member);
3490 if (this is PropertyBasedMember) {
3491 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
3492 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3494 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3495 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3503 protected static bool CheckAccessModifiers (MemberCore this_member, MemberSpec base_member)
3505 var thisp = this_member.ModFlags & Modifiers.AccessibilityMask;
3506 var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask;
3508 if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
3510 // It must be at least "protected"
3512 if ((thisp & Modifiers.PROTECTED) == 0) {
3517 // when overriding protected internal, the method can be declared
3518 // protected internal only within the same assembly or assembly
3519 // which has InternalsVisibleTo
3521 if ((thisp & Modifiers.INTERNAL) != 0) {
3522 return base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly);
3526 // protected overriding protected internal inside same assembly
3527 // requires internal modifier as well
3529 if (base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly)) {
3536 return thisp == base_classp;
3539 public override bool Define ()
3542 ModFlags = Modifiers.PUBLIC | Modifiers.ABSTRACT |
3543 Modifiers.VIRTUAL | (ModFlags & (Modifiers.UNSAFE | Modifiers.NEW));
3545 flags = MethodAttributes.Public |
3546 MethodAttributes.Abstract |
3547 MethodAttributes.HideBySig |
3548 MethodAttributes.NewSlot |
3549 MethodAttributes.Virtual;
3551 Parent.PartialContainer.MethodModifiersValid (this);
3553 flags = ModifiersExtensions.MethodAttr (ModFlags);
3556 if (IsExplicitImpl) {
3557 InterfaceType = MemberName.ExplicitInterface.ResolveAsType (Parent);
3558 if (InterfaceType == null)
3561 if ((ModFlags & Modifiers.PARTIAL) != 0) {
3562 Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
3563 GetSignatureForError ());
3566 if (!InterfaceType.IsInterface) {
3567 Report.SymbolRelatedToPreviousError (InterfaceType);
3568 Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface",
3569 InterfaceType.GetSignatureForError ());
3571 Parent.PartialContainer.VerifyImplements (this);
3574 Modifiers allowed_explicit = Modifiers.AllowedExplicitImplFlags;
3576 allowed_explicit |= Modifiers.ASYNC;
3578 ModifiersExtensions.Check (allowed_explicit, explicit_mod_flags, 0, Location, Report);
3581 return base.Define ();
3584 protected bool DefineParameters (ParametersCompiled parameters)
3586 if (!parameters.Resolve (this))
3590 for (int i = 0; i < parameters.Count; ++i) {
3591 Parameter p = parameters [i];
3593 if (p.HasDefaultValue && (IsExplicitImpl || this is Operator || (this is Indexer && parameters.Count == 1)))
3594 p.Warning_UselessOptionalParameter (Report);
3596 if (p.CheckAccessibility (this))
3599 TypeSpec t = parameters.Types [i];
3600 Report.SymbolRelatedToPreviousError (t);
3601 if (this is Indexer)
3602 Report.Error (55, Location,
3603 "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3604 t.GetSignatureForError (), GetSignatureForError ());
3605 else if (this is Operator)
3606 Report.Error (57, Location,
3607 "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3608 t.GetSignatureForError (), GetSignatureForError ());
3610 Report.Error (51, Location,
3611 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3612 t.GetSignatureForError (), GetSignatureForError ());
3618 protected override void DoMemberTypeDependentChecks ()
3620 base.DoMemberTypeDependentChecks ();
3622 VarianceDecl.CheckTypeVariance (MemberType, ExpectedMemberTypeVariance, this);
3625 public override void Emit()
3627 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3628 // We are more strict than csc and report this as an error because SRE does not allow emit that
3629 if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) {
3630 if (this is Constructor) {
3631 Report.Warning (824, 1, Location,
3632 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3634 Report.Warning (626, 1, Location,
3635 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3636 GetSignatureForError ());
3643 public override bool EnableOverloadChecks (MemberCore overload)
3646 // Two members can differ in their explicit interface
3647 // type parameter only
3649 InterfaceMemberBase imb = overload as InterfaceMemberBase;
3650 if (imb != null && imb.IsExplicitImpl) {
3651 if (IsExplicitImpl) {
3652 caching_flags |= Flags.MethodOverloadsExist;
3657 return IsExplicitImpl;
3660 protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member)
3662 var base_modifiers = base_member.Modifiers;
3664 // Remove internal modifier from types which are not internally accessible
3665 if ((base_modifiers & Modifiers.AccessibilityMask) == (Modifiers.PROTECTED | Modifiers.INTERNAL) &&
3666 !base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly))
3667 base_modifiers = Modifiers.PROTECTED;
3669 Report.SymbolRelatedToPreviousError (base_member);
3670 Report.Error (507, member.Location,
3671 "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3672 member.GetSignatureForError (),
3673 ModifiersExtensions.AccessibilityName (base_modifiers),
3674 base_member.GetSignatureForError ());
3677 protected void Error_StaticReturnType ()
3679 Report.Error (722, Location,
3680 "`{0}': static types cannot be used as return types",
3681 MemberType.GetSignatureForError ());
3685 /// Gets base method and its return type
3687 protected virtual MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
3689 return MemberCache.FindBaseMember (this, out bestCandidate, ref overrides);
3693 // The "short" name of this property / indexer / event. This is the
3694 // name without the explicit interface.
3696 public string ShortName {
3697 get { return MemberName.Name; }
3701 // Returns full metadata method name
3703 public string GetFullName (MemberName name)
3705 return GetFullName (name.Name);
3708 public string GetFullName (string name)
3710 if (!IsExplicitImpl)
3714 // When dealing with explicit members a full interface type
3715 // name is added to member name to avoid possible name conflicts
3717 // We use CSharpName which gets us full name with benefit of
3718 // replacing predefined names which saves some space and name
3721 return InterfaceType.GetSignatureForError () + "." + name;
3724 public override string GetSignatureForDocumentation ()
3727 return Parent.GetSignatureForDocumentation () + "." + InterfaceType.GetSignatureForDocumentation (true) + "#" + ShortName;
3729 return Parent.GetSignatureForDocumentation () + "." + ShortName;
3732 public override bool IsUsed
3734 get { return IsExplicitImpl || base.IsUsed; }
3737 public override void SetConstraints (List<Constraints> constraints_list)
3739 if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
3740 Report.Error (460, Location,
3741 "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
3742 GetSignatureForError ());
3745 base.SetConstraints (constraints_list);
3749 public abstract class MemberBase : MemberCore
3751 protected FullNamedExpression type_expr;
3752 protected TypeSpec member_type;
3753 public new TypeDefinition Parent;
3755 protected MemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
3756 : base (parent, name, attrs)
3758 this.Parent = parent;
3759 this.type_expr = type;
3761 if (name != MemberName.Null)
3762 ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
3767 public TypeSpec MemberType {
3773 public FullNamedExpression TypeExpression {
3785 // Main member define entry
3787 public override bool Define ()
3789 DoMemberTypeIndependentChecks ();
3792 // Returns false only when type resolution failed
3794 if (!ResolveMemberType ())
3797 DoMemberTypeDependentChecks ();
3802 // Any type_name independent checks
3804 protected virtual void DoMemberTypeIndependentChecks ()
3806 if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
3807 (ModFlags & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
3808 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
3809 GetSignatureForError (), Parent.GetSignatureForError ());
3814 // Any type_name dependent checks
3816 protected virtual void DoMemberTypeDependentChecks ()
3818 // verify accessibility
3819 if (!IsAccessibleAs (MemberType)) {
3820 Report.SymbolRelatedToPreviousError (MemberType);
3821 if (this is Property)
3822 Report.Error (53, Location,
3823 "Inconsistent accessibility: property type `" +
3824 MemberType.GetSignatureForError () + "' is less " +
3825 "accessible than property `" + GetSignatureForError () + "'");
3826 else if (this is Indexer)
3827 Report.Error (54, Location,
3828 "Inconsistent accessibility: indexer return type `" +
3829 MemberType.GetSignatureForError () + "' is less " +
3830 "accessible than indexer `" + GetSignatureForError () + "'");
3831 else if (this is MethodCore) {
3832 if (this is Operator)
3833 Report.Error (56, Location,
3834 "Inconsistent accessibility: return type `" +
3835 MemberType.GetSignatureForError () + "' is less " +
3836 "accessible than operator `" + GetSignatureForError () + "'");
3838 Report.Error (50, Location,
3839 "Inconsistent accessibility: return type `" +
3840 MemberType.GetSignatureForError () + "' is less " +
3841 "accessible than method `" + GetSignatureForError () + "'");
3842 } else if (this is Event) {
3843 Report.Error (7025, Location,
3844 "Inconsistent accessibility: event type `{0}' is less accessible than event `{1}'",
3845 MemberType.GetSignatureForError (), GetSignatureForError ());
3847 Report.Error (52, Location,
3848 "Inconsistent accessibility: field type `" +
3849 MemberType.GetSignatureForError () + "' is less " +
3850 "accessible than field `" + GetSignatureForError () + "'");
3855 protected void IsTypePermitted ()
3857 if (MemberType.IsSpecialRuntimeType) {
3858 if (Parent is StateMachine) {
3859 Report.Error (4012, Location,
3860 "Parameters or local variables of type `{0}' cannot be declared in async methods or iterators",
3861 MemberType.GetSignatureForError ());
3862 } else if (Parent is HoistedStoreyClass) {
3863 Report.Error (4013, Location,
3864 "Local variables of type `{0}' cannot be used inside anonymous methods, lambda expressions or query expressions",
3865 MemberType.GetSignatureForError ());
3867 Report.Error (610, Location,
3868 "Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ());
3873 protected virtual bool CheckBase ()
3875 CheckProtectedModifier ();
3880 public override string GetSignatureForDocumentation ()
3882 return Parent.GetSignatureForDocumentation () + "." + MemberName.Basename;
3885 public virtual void PrepareEmit ()
3887 if (member_type != null && type_expr != null)
3888 member_type.CheckObsoleteness (this, type_expr.Location);
3891 protected virtual bool ResolveMemberType ()
3893 if (member_type != null)
3894 throw new InternalErrorException ("Multi-resolve");
3896 member_type = type_expr.ResolveAsType (this);
3897 return member_type != null;