X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fclass.cs;h=95a628e102d0cf8e9d97e4f1f0401aa00b6f24fc;hb=f3edca943070399b06d33f3ba3e99c76a9d9886d;hp=5b120b161c71e468d7f8dc2a07b93745d9cc7db2;hpb=694ab7d8477ba306f75ee1cb71ec8acd87788f67;p=mono.git diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs index 5b120b161c7..95a628e102d 100644 --- a/mcs/mcs/class.cs +++ b/mcs/mcs/class.cs @@ -18,6 +18,9 @@ using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Linq; +using System.Text; +using System.Diagnostics; +using Mono.CompilerServices.SymbolWriter; #if NET_2_1 using XmlElement = System.Object; @@ -35,17 +38,357 @@ using System.Reflection.Emit; namespace Mono.CSharp { - - public interface ITypesContainer + // + // General types container, used as a base class for all constructs which can hold types + // + public abstract class TypeContainer : MemberCore { - Location Location { get; } - MemberName MemberName { get; } + public readonly MemberKind Kind; + public readonly string Basename; + + protected List containers; + + TypeDefinition main_container; + + protected Dictionary defined_names; + + protected bool is_defined; + + public TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind) + : base (parent, name, attrs) + { + this.Kind = kind; + if (name != null) + this.Basename = name.Basename; + + defined_names = new Dictionary (); + } + + public override TypeSpec CurrentType { + get { + return null; + } + } + + public Dictionary DefinedNames { + get { + return defined_names; + } + } + + public TypeDefinition PartialContainer { + get { + return main_container; + } + protected set { + main_container = value; + } + } + + public IList Containers { + get { + return containers; + } + } + + // + // Any unattached attributes during parsing get added here. User + // by FULL_AST mode + // + public Attributes UnattachedAttributes { + get; set; + } + + public virtual void AddCompilerGeneratedClass (CompilerGeneratedContainer c) + { + containers.Add (c); + } + + public virtual void AddPartial (TypeDefinition next_part) + { + MemberCore mc; + (PartialContainer ?? this).defined_names.TryGetValue (next_part.Basename, out mc); + + AddPartial (next_part, mc as TypeDefinition); + } + + protected void AddPartial (TypeDefinition next_part, TypeDefinition existing) + { + next_part.ModFlags |= Modifiers.PARTIAL; + + if (existing == null) { + AddTypeContainer (next_part); + return; + } + + if ((existing.ModFlags & Modifiers.PARTIAL) == 0) { + if (existing.Kind != next_part.Kind) { + AddTypeContainer (next_part); + } else { + Report.SymbolRelatedToPreviousError (next_part); + Error_MissingPartialModifier (existing); + } + + return; + } + + if (existing.Kind != next_part.Kind) { + Report.SymbolRelatedToPreviousError (existing); + Report.Error (261, next_part.Location, + "Partial declarations of `{0}' must be all classes, all structs or all interfaces", + next_part.GetSignatureForError ()); + } + + if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) && + ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 && + (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) { + Report.SymbolRelatedToPreviousError (existing); + Report.Error (262, next_part.Location, + "Partial declarations of `{0}' have conflicting accessibility modifiers", + next_part.GetSignatureForError ()); + } + + var tc_names = existing.CurrentTypeParameters; + if (tc_names != null) { + for (int i = 0; i < tc_names.Count; ++i) { + var tp = next_part.MemberName.TypeParameters[i]; + if (tc_names[i].MemberName.Name != tp.MemberName.Name) { + Report.SymbolRelatedToPreviousError (existing.Location, ""); + Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order", + next_part.GetSignatureForError ()); + break; + } + + if (tc_names[i].Variance != tp.Variance) { + Report.SymbolRelatedToPreviousError (existing.Location, ""); + Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers", + next_part.GetSignatureForError ()); + break; + } + } + } + + if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) { + existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask); + } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) { + existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask); + existing.ModFlags |= next_part.ModFlags; + } else { + existing.ModFlags |= next_part.ModFlags; + } + + existing.Definition.Modifiers = existing.ModFlags; + + if (next_part.attributes != null) { + if (existing.attributes == null) + existing.attributes = next_part.attributes; + else + existing.attributes.AddAttributes (next_part.attributes.Attrs); + } + + next_part.PartialContainer = existing; + + if (containers == null) + containers = new List (); + + containers.Add (next_part); + } + + public virtual void AddTypeContainer (TypeContainer tc) + { + containers.Add (tc); + + var tparams = tc.MemberName.TypeParameters; + if (tparams != null && tc.PartialContainer != null) { + var td = (TypeDefinition) tc; + for (int i = 0; i < tparams.Count; ++i) { + var tp = tparams[i]; + if (tp.MemberName == null) + continue; + + td.AddNameToContainer (tp, tp.Name); + } + } + } + + public virtual void CloseContainer () + { + if (containers != null) { + foreach (TypeContainer tc in containers) { + tc.CloseContainer (); + } + } + } + + public virtual void CreateMetadataName (StringBuilder sb) + { + if (Parent != null && Parent.MemberName != null) + Parent.CreateMetadataName (sb); + + MemberName.CreateMetadataName (sb); + } + + public virtual bool CreateContainer () + { + if (containers != null) { + foreach (TypeContainer tc in containers) { + tc.CreateContainer (); + } + } + + return true; + } + + public override bool Define () + { + if (containers != null) { + foreach (TypeContainer tc in containers) { + tc.Define (); + } + } + + // Release cache used by parser only + if (Module.Evaluator == null) { + defined_names = null; + } else { + defined_names.Clear (); + } + + return true; + } + + public virtual void PrepareEmit () + { + if (containers != null) { + foreach (var t in containers) { + try { + t.PrepareEmit (); + } catch (Exception e) { + if (MemberName == MemberName.Null) + throw; + + throw new InternalErrorException (t, e); + } + } + } + } + + public virtual bool DefineContainer () + { + if (is_defined) + return true; + + is_defined = true; + + DoDefineContainer (); + + if (containers != null) { + foreach (TypeContainer tc in containers) { + try { + tc.DefineContainer (); + } catch (Exception e) { + if (MemberName == MemberName.Null) + throw; + + throw new InternalErrorException (tc, e); + } + } + } + + return true; + } + + protected virtual void DefineNamespace () + { + if (containers != null) { + foreach (var tc in containers) { + try { + tc.DefineNamespace (); + } catch (Exception e) { + throw new InternalErrorException (tc, e); + } + } + } + } + + protected virtual void DoDefineContainer () + { + } + + public virtual void EmitContainer () + { + if (containers != null) { + for (int i = 0; i < containers.Count; ++i) + containers[i].EmitContainer (); + } + } + + protected void Error_MissingPartialModifier (MemberCore type) + { + Report.Error (260, type.Location, + "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists", + type.GetSignatureForError ()); + } + + public override string GetSignatureForDocumentation () + { + if (Parent != null && Parent.MemberName != null) + return Parent.GetSignatureForDocumentation () + "." + MemberName.GetSignatureForDocumentation (); + + return MemberName.GetSignatureForDocumentation (); + } + + public override string GetSignatureForError () + { + if (Parent != null && Parent.MemberName != null) + return Parent.GetSignatureForError () + "." + MemberName.GetSignatureForError (); + + return MemberName.GetSignatureForError (); + } + + public string GetSignatureForMetadata () + { +#if STATIC + if (Parent is TypeDefinition) { + return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (MemberName.Basename); + } + + var sb = new StringBuilder (); + CreateMetadataName (sb); + return sb.ToString (); +#else + throw new NotImplementedException (); +#endif + } + + public virtual void RemoveContainer (TypeContainer cont) + { + if (containers != null) + containers.Remove (cont); + + var tc = Parent == Module ? Module : this; + tc.defined_names.Remove (cont.Basename); + } + + public virtual void VerifyMembers () + { + if (containers != null) { + foreach (TypeContainer tc in containers) + tc.VerifyMembers (); + } + } + + public override void WriteDebugSymbol (MonoSymbolFile file) + { + if (containers != null) { + foreach (TypeContainer tc in containers) { + tc.WriteDebugSymbol (file); + } + } + } } - /// - /// This is the base class for structs and classes. - /// - public abstract class TypeContainer : DeclSpace, ITypeDefinition, ITypesContainer + public abstract class TypeDefinition : TypeContainer, ITypeDefinition { // // Different context is needed when resolving type container base @@ -71,7 +414,7 @@ namespace Mono.CSharp get { return tc.Parent.CurrentType; } } - public TypeParameter[] CurrentTypeParameters { + public TypeParameters CurrentTypeParameters { get { return tc.PartialContainer.CurrentTypeParameters; } } @@ -113,9 +456,9 @@ namespace Mono.CSharp public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc) { if (arity == 0) { - TypeParameter[] tp = CurrentTypeParameters; + var tp = CurrentTypeParameters; if (tp != null) { - TypeParameter t = TypeParameter.FindTypeParameter (tp, name); + TypeParameter t = tp.Find (name); if (t != null) return new TypeParameterExpr (t, loc); } @@ -135,24 +478,7 @@ namespace Mono.CSharp HasStaticFieldInitializer = 1 << 2 } - - // Whether this is a struct, class or interface - public readonly MemberKind Kind; - - // Holds a list of classes and structures - protected List types; - - List ordered_explicit_member_list; - List ordered_member_list; - - // Holds the list of properties - List properties; - - // Holds the list of constructors - protected List instance_constructors; - - // Holds the list of fields - protected List fields; + readonly List members; // Holds a list of fields that have initializers protected List initialized_fields; @@ -160,41 +486,17 @@ namespace Mono.CSharp // Holds a list of static fields that have initializers protected List initialized_static_fields; - // Holds the list of constants - protected List constants; - - // Holds the methods. - List methods; - - // Holds the events - protected List events; - - // Holds the indexers - List indexers; - - // Holds the operators - List operators; - - // Holds the compiler generated classes - protected List compiler_generated; - Dictionary hoisted_base_call_proxies; Dictionary Cache = new Dictionary (); - // - // Pointers to the default constructor and the default static constructor - // - protected Constructor default_constructor; - protected Constructor default_static_constructor; - // // Points to the first non-static field added to the container. // // This is an arbitrary choice. We are interested in looking at _some_ non-static field, // and the first one's as good as any. // - FieldBase first_nonstatic_field; + protected FieldBase first_nonstatic_field; // // This one is computed after we can distinguish interfaces @@ -206,29 +508,35 @@ namespace Mono.CSharp protected List type_bases; - bool members_defined; - bool members_defined_ok; - bool type_defined; - - TypeContainer InTransit; + TypeDefinition InTransit; + public TypeBuilder TypeBuilder; GenericTypeParameterBuilder[] all_tp_builders; + // + // All recursive type parameters put together sharing same + // TypeParameter instances + // + TypeParameters all_type_parameters; public const string DefaultIndexerName = "Item"; - private bool seen_normal_indexers = false; - private string indexer_name = DefaultIndexerName; + bool has_normal_indexers; + string indexer_name; protected bool requires_delayed_unmanagedtype_check; bool error; + bool members_defined; + bool members_defined_ok; + protected bool has_static_constructor; private CachedMethods cached_method; protected TypeSpec spec; TypeSpec current_type; - List partial_parts; - public int DynamicSitesCounter; + public int AnonymousMethodsCounter; + + static readonly string[] attribute_targets = new string[] { "type" }; /// /// The pending methods that need to be implemented @@ -236,15 +544,11 @@ namespace Mono.CSharp /// PendingImplementation pending; - public TypeContainer (NamespaceContainer ns, DeclSpace parent, MemberName name, - Attributes attrs, MemberKind kind) - : base (ns, parent, name, attrs) + public TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind) + : base (parent, name, attrs, kind) { - if (parent != null && parent.NamespaceEntry != ns) - throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class"); - - this.Kind = kind; - this.PartialContainer = this; + PartialContainer = this; + members = new List (); } #region Properties @@ -258,11 +562,11 @@ namespace Mono.CSharp public override TypeSpec CurrentType { get { if (current_type == null) { - if (IsGeneric) { + if (IsGenericOrParentIsGeneric) { // // Switch to inflated version as it's used by all expressions // - var targs = CurrentTypeParameters == null ? TypeSpec.EmptyTypes : CurrentTypeParameters.Select (l => l.Type).ToArray (); + var targs = CurrentTypeParameters == null ? TypeSpec.EmptyTypes : CurrentTypeParameters.Types; current_type = spec.MakeGenericType (this, targs); } else { current_type = spec; @@ -273,9 +577,9 @@ namespace Mono.CSharp } } - public override TypeParameter[] CurrentTypeParameters { + public override TypeParameters CurrentTypeParameters { get { - return PartialContainer.type_params; + return PartialContainer.MemberName.TypeParameters; } } @@ -283,7 +587,7 @@ namespace Mono.CSharp get { int total = all_tp_builders.Length; if (CurrentTypeParameters != null) { - return total - CurrentTypeParameters.Length; + return total - CurrentTypeParameters.Count; } return total; } @@ -313,291 +617,244 @@ namespace Mono.CSharp } } - public TypeSpec[] Interfaces { + public bool HasInstanceConstructor { get { - return iface_exprs; + return (caching_flags & Flags.HasInstanceConstructor) != 0; + } + set { + caching_flags |= Flags.HasInstanceConstructor; } } - #endregion - - public override void Accept (StructuralVisitor visitor) - { - visitor.Visit (this); + // Indicated whether container has StructLayout attribute set Explicit + public bool HasExplicitLayout { + get { return (caching_flags & Flags.HasExplicitLayout) != 0; } + set { caching_flags |= Flags.HasExplicitLayout; } } - public bool AddMember (MemberCore symbol) - { - return AddToContainer (symbol, symbol.MemberName.Basename); + public bool HasOperators { + get { + return (caching_flags & Flags.HasUserOperators) != 0; + } + set { + caching_flags |= Flags.HasUserOperators; + } } - public bool AddMember (MemberCore symbol, string name) - { - return AddToContainer (symbol, name); + public bool HasStructLayout { + get { return (caching_flags & Flags.HasStructLayout) != 0; } + set { caching_flags |= Flags.HasStructLayout; } } - protected virtual bool AddMemberType (TypeContainer ds) - { - return AddToContainer (ds, ds.Basename); + public TypeSpec[] Interfaces { + get { + return iface_exprs; + } } - protected virtual void RemoveMemberType (TypeContainer ds) - { - RemoveFromContainer (ds.Basename); + public bool IsGenericOrParentIsGeneric { + get { + return all_type_parameters != null; + } } - public void AddConstant (Const constant) - { - if (!AddMember (constant)) - return; - - if (constants == null) - constants = new List (); - - constants.Add (constant); + public bool IsTopLevel { + get { + return !(Parent is TypeDefinition); + } } - public TypeContainer AddTypeContainer (TypeContainer tc) - { - if (!AddMemberType (tc)) - return tc; + public bool IsPartial { + get { + return (ModFlags & Modifiers.PARTIAL) != 0; + } + } - if (types == null) - types = new List (); + // + // Returns true for secondary partial containers + // + bool IsPartialPart { + get { + return PartialContainer != this; + } + } - types.Add (tc); - return tc; + public MemberCache MemberCache { + get { + return spec.MemberCache; + } } - public virtual TypeContainer AddPartial (TypeContainer next_part) - { - return AddPartial (next_part, next_part.Basename); + public List Members { + get { + return members; + } } - protected TypeContainer AddPartial (TypeContainer next_part, string name) - { - next_part.ModFlags |= Modifiers.PARTIAL; - TypeContainer tc = GetDefinition (name) as TypeContainer; - if (tc == null) - return AddTypeContainer (next_part); + string ITypeDefinition.Namespace { + get { + var p = Parent; + while (p.Kind != MemberKind.Namespace) + p = p.Parent; - if ((tc.ModFlags & Modifiers.PARTIAL) == 0) { - Report.SymbolRelatedToPreviousError (next_part); - Error_MissingPartialModifier (tc); + return p.MemberName == null ? null : p.GetSignatureForError (); } + } - if (tc.Kind != next_part.Kind) { - Report.SymbolRelatedToPreviousError (tc); - Report.Error (261, next_part.Location, - "Partial declarations of `{0}' must be all classes, all structs or all interfaces", - next_part.GetSignatureForError ()); + public TypeParameters TypeParametersAll { + get { + return all_type_parameters; } + } - if ((tc.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) && - ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 && - (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) { - Report.SymbolRelatedToPreviousError (tc); - Report.Error (262, next_part.Location, - "Partial declarations of `{0}' have conflicting accessibility modifiers", - next_part.GetSignatureForError ()); + public override string[] ValidAttributeTargets { + get { + return attribute_targets; } + } - if (tc.partial_parts == null) - tc.partial_parts = new List (1); - - if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) { - tc.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask); - } else if ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) { - tc.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask); - tc.ModFlags |= next_part.ModFlags; - } else { - tc.ModFlags |= next_part.ModFlags; - } + #endregion - tc.spec.Modifiers = tc.ModFlags; + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } - if (next_part.attributes != null) { - if (tc.attributes == null) - tc.attributes = next_part.attributes; - else - tc.attributes.AddAttributes (next_part.attributes.Attrs); + public void AddMember (MemberCore symbol) + { + if (symbol.MemberName.ExplicitInterface != null) { + if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) { + Report.Error (541, symbol.Location, + "`{0}': explicit interface declaration can only be declared in a class or struct", + symbol.GetSignatureForError ()); + } } - next_part.PartialContainer = tc; - tc.partial_parts.Add (next_part); - return tc; + AddNameToContainer (symbol, symbol.MemberName.Basename); + members.Add (symbol); } - public virtual void RemoveTypeContainer (TypeContainer next_part) + public override void AddTypeContainer (TypeContainer tc) { - if (types != null) - types.Remove (next_part); + AddNameToContainer (tc, tc.Basename); + + if (containers == null) + containers = new List (); - Cache.Remove (next_part.Basename); - RemoveMemberType (next_part); + members.Add (tc); + base.AddTypeContainer (tc); } - - public void AddDelegate (Delegate d) + + public override void AddCompilerGeneratedClass (CompilerGeneratedContainer c) { - AddTypeContainer (d); + members.Add (c); + + if (containers == null) + containers = new List (); + + base.AddCompilerGeneratedClass (c); } - private void AddMemberToList (MemberCore mc, List alist, bool isexplicit) + // + // Adds the member to defined_names table. It tests for duplications and enclosing name conflicts + // + public virtual void AddNameToContainer (MemberCore symbol, string name) { - if (ordered_explicit_member_list == null) { - ordered_explicit_member_list = new List (); - ordered_member_list = new List (); + if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0) + return; + + MemberCore mc; + if (!PartialContainer.defined_names.TryGetValue (name, out mc)) { + PartialContainer.defined_names.Add (name, symbol); + return; } - if (isexplicit) { - if (Kind == MemberKind.Interface) { - Report.Error (541, mc.Location, - "`{0}': explicit interface declaration can only be declared in a class or struct", - mc.GetSignatureForError ()); - } + if (symbol.EnableOverloadChecks (mc)) + return; - ordered_explicit_member_list.Add (mc); - alist.Insert (0, mc); + InterfaceMemberBase im = mc as InterfaceMemberBase; + if (im != null && im.IsExplicitImpl) + return; + + Report.SymbolRelatedToPreviousError (mc); + if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) { + Error_MissingPartialModifier (symbol); + return; + } + + if (symbol is TypeParameter) { + Report.Error (692, symbol.Location, + "Duplicate type parameter `{0}'", symbol.GetSignatureForError ()); } else { - ordered_member_list.Add (mc); - alist.Add (mc); + Report.Error (102, symbol.Location, + "The type `{0}' already contains a definition for `{1}'", + GetSignatureForError (), name); } + return; } - - public void AddMethod (MethodOrOperator method) + + public void AddConstructor (Constructor c) { - if (!AddToContainer (method, method.MemberName.Basename)) - return; - - if (methods == null) - methods = new List (); - - if (method.MemberName.Left != null) - AddMemberToList (method, methods, true); - else - AddMemberToList (method, methods, false); + AddConstructor (c, false); } - public void AddConstructor (Constructor c) + public void AddConstructor (Constructor c, bool isDefault) { bool is_static = (c.ModFlags & Modifiers.STATIC) != 0; - if (!AddToContainer (c, is_static ? Constructor.ConstructorName : Constructor.TypeConstructorName)) - return; - - if (is_static && c.ParameterInfo.IsEmpty){ - if (default_static_constructor != null) { - Report.SymbolRelatedToPreviousError (default_static_constructor); - Report.Error (111, c.Location, - "A member `{0}' is already defined. Rename this member or use different parameter types", - c.GetSignatureForError ()); - return; - } + if (!isDefault) + AddNameToContainer (c, is_static ? Constructor.TypeConstructorName : Constructor.ConstructorName); - default_static_constructor = c; + if (is_static && c.ParameterInfo.IsEmpty) { + PartialContainer.has_static_constructor = true; } else { - if (c.ParameterInfo.IsEmpty) - default_constructor = c; - - if (instance_constructors == null) - instance_constructors = new List (); - - instance_constructors.Add (c); + PartialContainer.HasInstanceConstructor = true; } + + members.Add (c); } public bool AddField (FieldBase field) { - if (!AddMember (field)) - return false; - - if (fields == null) - fields = new List (); - - fields.Add (field); + AddMember (field); if ((field.ModFlags & Modifiers.STATIC) != 0) return true; - if (first_nonstatic_field == null) { - first_nonstatic_field = field; + var first_field = PartialContainer.first_nonstatic_field; + if (first_field == null) { + PartialContainer.first_nonstatic_field = field; return true; } - if (Kind == MemberKind.Struct && first_nonstatic_field.Parent != field.Parent) { - Report.SymbolRelatedToPreviousError (first_nonstatic_field.Parent); + if (Kind == MemberKind.Struct && first_field.Parent != field.Parent) { + Report.SymbolRelatedToPreviousError (first_field.Parent); Report.Warning (282, 3, field.Location, "struct instance field `{0}' found in different declaration from instance field `{1}'", - field.GetSignatureForError (), first_nonstatic_field.GetSignatureForError ()); + field.GetSignatureForError (), first_field.GetSignatureForError ()); } return true; } - public void AddProperty (Property prop) - { - if (!AddMember (prop)) - return; - - if (properties == null) - properties = new List (); - - if (prop.MemberName.Left != null) - AddMemberToList (prop, properties, true); - else - AddMemberToList (prop, properties, false); - } - - public void AddEvent (Event e) - { - if (!AddMember (e)) - return; - - if (events == null) - events = new List (); - - events.Add (e); - } - /// /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute /// public void AddIndexer (Indexer i) { - if (indexers == null) - indexers = new List (); - - if (i.IsExplicitImpl) - AddMemberToList (i, indexers, true); - else - AddMemberToList (i, indexers, false); + members.Add (i); } public void AddOperator (Operator op) { - if (!AddMember (op)) - return; - - if (operators == null) - operators = new List (); - - operators.Add (op); - } - - public void AddCompilerGeneratedClass (CompilerGeneratedClass c) - { - if (compiler_generated == null) - compiler_generated = new List (); - - compiler_generated.Add (c); + PartialContainer.HasOperators = true; + AddMember (op); } public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { - if (a.Type == pa.DefaultMember) { - if (Indexers != null) { - Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer"); - return; - } + if (has_normal_indexers && a.Type == pa.DefaultMember) { + Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer"); + return; } if (a.Type == pa.Required) { @@ -614,67 +871,13 @@ namespace Mono.CSharp } } - public IList Types { - get { - return types; - } - } - - public IList Methods { - get { - return methods; - } - } - - public IList Constants { - get { - return constants; - } - } - public TypeSpec BaseType { get { return spec.BaseType; } } - public IList Fields { - get { - return fields; - } - } - - public IList InstanceConstructors { - get { - return instance_constructors; - } - } - - public IList Properties { - get { - return properties; - } - } - - public IList Events { - get { - return events; - } - } - - public IList Indexers { - get { - return indexers; - } - } - - public IList Operators { - get { - return operators; - } - } - - protected override TypeAttributes TypeAttr { + protected virtual TypeAttributes TypeAttr { get { return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel); } @@ -688,14 +891,13 @@ namespace Mono.CSharp TypeParameterSpec[] ITypeDefinition.TypeParameters { get { - // TODO MemberCache: this is going to hurt - return PartialContainer.type_params.Select (l => l.Type).ToArray (); + return PartialContainer.CurrentTypeParameters.Types; } } public string GetAttributeDefaultMember () { - return indexers == null ? DefaultIndexerName : indexer_name; + return indexer_name ?? DefaultIndexerName; } public bool IsComImport { @@ -703,21 +905,18 @@ namespace Mono.CSharp if (OptAttributes == null) return false; - return OptAttributes.Contains (Module.PredefinedAttributes.ComImport); - } - } - - string ITypeDefinition.Namespace { - get { - return NamespaceEntry.NS.MemberName.GetSignatureForError (); + return OptAttributes.Contains (Module.PredefinedAttributes.ComImport); } } public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression) { + if (IsPartialPart) + PartialContainer.RegisterFieldForInitialization (field, expression); + if ((field.ModFlags & Modifiers.STATIC) != 0){ if (initialized_static_fields == null) { - PartialContainer.HasStaticFieldInitializer = true; + HasStaticFieldInitializer = true; initialized_static_fields = new List (4); } @@ -732,16 +931,8 @@ namespace Mono.CSharp public void ResolveFieldInitializers (BlockContext ec) { - if (partial_parts != null) { - foreach (TypeContainer part in partial_parts) { - part.DoResolveFieldInitializers (ec); - } - } - DoResolveFieldInitializers (ec); - } + Debug.Assert (!IsPartialPart); - void DoResolveFieldInitializers (BlockContext ec) - { if (ec.IsStatic) { if (initialized_static_fields == null) return; @@ -814,46 +1005,13 @@ namespace Mono.CSharp internal override void GenerateDocComment (DocumentationBuilder builder) { - base.GenerateDocComment (builder); - - if (DefaultStaticConstructor != null) - DefaultStaticConstructor.GenerateDocComment (builder); - - if (InstanceConstructors != null) - foreach (Constructor c in InstanceConstructors) - c.GenerateDocComment (builder); - - if (Types != null) - foreach (TypeContainer tc in Types) - tc.GenerateDocComment (builder); - - if (Constants != null) - foreach (Const c in Constants) - c.GenerateDocComment (builder); - - if (Fields != null) - foreach (FieldBase f in Fields) - f.GenerateDocComment (builder); - - if (Events != null) - foreach (Event e in Events) - e.GenerateDocComment (builder); - - if (Indexers != null) - foreach (Indexer ix in Indexers) - ix.GenerateDocComment (builder); - - if (Properties != null) - foreach (Property p in Properties) - p.GenerateDocComment (builder); + if (IsPartialPart) + return; - if (Methods != null) - foreach (MethodOrOperator m in Methods) - m.GenerateDocComment (builder); + base.GenerateDocComment (builder); - if (Operators != null) - foreach (Operator o in Operators) - o.GenerateDocComment (builder); + foreach (var member in members) + member.GenerateDocComment (builder); } public TypeSpec GetAttributeCoClass () @@ -881,11 +1039,21 @@ namespace Mono.CSharp return a.GetAttributeUsageAttribute (); } - public virtual void AddBasesForPart (DeclSpace part, List bases) + public virtual CompilationSourceFile GetCompilationSourceFile () + { + TypeContainer ns = Parent; + while (true) { + var sf = ns as CompilationSourceFile; + if (sf != null) + return sf; + + ns = ns.Parent; + } + } + + public virtual void AddBasesForPart (List bases) { - // FIXME: get rid of partial_parts and store lists of bases of each part here - // assumed, not verified: 'part' is in 'partial_parts' - ((TypeContainer) part).type_bases = bases; + type_bases = bases; } /// @@ -963,44 +1131,6 @@ namespace Mono.CSharp return ifaces; } - TypeSpec[] GetNormalPartialBases () - { - var ifaces = new List (0); - if (iface_exprs != null) - ifaces.AddRange (iface_exprs); - - foreach (TypeContainer part in partial_parts) { - FullNamedExpression new_base_class; - var new_ifaces = part.ResolveBaseTypes (out new_base_class); - if (new_base_class != null) { - if (base_type_expr != null && part.base_type != base_type) { - Report.SymbolRelatedToPreviousError (new_base_class.Location, ""); - Report.Error (263, part.Location, - "Partial declarations of `{0}' must not specify different base classes", - part.GetSignatureForError ()); - } else { - base_type_expr = new_base_class; - base_type = part.base_type; - } - } - - if (new_ifaces == null) - continue; - - foreach (var iface in new_ifaces) { - if (ifaces.Contains (iface)) - continue; - - ifaces.Add (iface); - } - } - - if (ifaces.Count == 0) - return null; - - return ifaces.ToArray (); - } - // // Checks that some operators come in pairs: // == and != @@ -1013,26 +1143,28 @@ namespace Mono.CSharp void CheckPairedOperators () { bool has_equality_or_inequality = false; - var operators = this.operators.ToArray (); - bool[] has_pair = new bool[operators.Length]; + List found_matched = new List (); - for (int i = 0; i < operators.Length; ++i) { - if (operators[i] == null) + for (int i = 0; i < members.Count; ++i) { + var o_a = members[i] as Operator; + if (o_a == null) continue; - Operator o_a = (Operator) operators[i]; - Operator.OpType o_type = o_a.OperatorType; + var o_type = o_a.OperatorType; if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality) has_equality_or_inequality = true; - Operator.OpType matching_type = o_a.GetMatchingOperator (); + if (found_matched.Contains (o_type)) + continue; + + var matching_type = o_a.GetMatchingOperator (); if (matching_type == Operator.OpType.TOP) { - operators[i] = null; continue; } - for (int ii = 0; ii < operators.Length; ++ii) { - Operator o_b = (Operator) operators[ii]; + bool pair_found = false; + for (int ii = i + 1; ii < members.Count; ++ii) { + var o_b = members[ii] as Operator; if (o_b == null || o_b.OperatorType != matching_type) continue; @@ -1042,47 +1174,56 @@ namespace Mono.CSharp if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes)) continue; - operators[i] = null; - - // - // Used to ignore duplicate user conversions - // - has_pair[ii] = true; + found_matched.Add (matching_type); + pair_found = true; + break; } - } - - for (int i = 0; i < operators.Length; ++i) { - if (operators[i] == null || has_pair[i]) - continue; - Operator o = (Operator) operators [i]; - Report.Error (216, o.Location, - "The operator `{0}' requires a matching operator `{1}' to also be defined", - o.GetSignatureForError (), Operator.GetName (o.GetMatchingOperator ())); + if (!pair_found) { + Report.Error (216, o_a.Location, + "The operator `{0}' requires a matching operator `{1}' to also be defined", + o_a.GetSignatureForError (), Operator.GetName (matching_type)); + } } if (has_equality_or_inequality) { - if (Methods == null || !HasEquals) + if (!HasEquals) Report.Warning (660, 2, Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", GetSignatureForError ()); - if (Methods == null || !HasGetHashCode) + if (!HasGetHashCode) Report.Warning (661, 2, Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", GetSignatureForError ()); } } + + public override void CreateMetadataName (StringBuilder sb) + { + if (Parent.MemberName != null) { + Parent.CreateMetadataName (sb); + + if (sb.Length != 0) { + sb.Append ("."); + } + } + + sb.Append (MemberName.Basename); + } bool CreateTypeBuilder () { // // Sets .size to 1 for structs with no instance fields // - int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0; + int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0; - if (IsTopLevel) { - TypeBuilder = Module.CreateBuilder (Name, TypeAttr, type_size); + var parent_def = Parent as TypeDefinition; + if (parent_def == null) { + var sb = new StringBuilder (); + CreateMetadataName (sb); + TypeBuilder = Module.CreateBuilder (sb.ToString (), TypeAttr, type_size); } else { - TypeBuilder = Parent.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size); + TypeBuilder = parent_def.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size); } if (DeclaringAssembly.Importer != null) @@ -1090,27 +1231,84 @@ namespace Mono.CSharp spec.SetMetaInfo (TypeBuilder); spec.MemberCache = new MemberCache (this); - spec.DeclaringType = Parent.CurrentType; - if (!IsTopLevel) - Parent.MemberCache.AddMember (spec); + TypeParameters parentAllTypeParameters = null; + if (parent_def != null) { + spec.DeclaringType = Parent.CurrentType; + parent_def.MemberCache.AddMember (spec); + parentAllTypeParameters = parent_def.all_type_parameters; + } - if (IsGeneric) { - string[] param_names = new string[TypeParameters.Length]; - for (int i = 0; i < TypeParameters.Length; i++) - param_names [i] = TypeParameters[i].Name; + if (MemberName.TypeParameters != null || parentAllTypeParameters != null) { + var tparam_names = CreateTypeParameters (parentAllTypeParameters); - all_tp_builders = TypeBuilder.DefineGenericParameters (param_names); + all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names); - int offset = CurrentTypeParametersStartIndex; - for (int i = offset; i < all_tp_builders.Length; i++) { - CurrentTypeParameters [i - offset].Define (all_tp_builders [i], spec); - } + if (CurrentTypeParameters != null) + CurrentTypeParameters.Define (all_tp_builders, spec, CurrentTypeParametersStartIndex, this); } return true; } + string[] CreateTypeParameters (TypeParameters parentAllTypeParameters) + { + string[] names; + int parent_offset = 0; + if (parentAllTypeParameters != null) { + if (CurrentTypeParameters == null) { + all_type_parameters = parentAllTypeParameters; + return parentAllTypeParameters.GetAllNames (); + } + + names = new string[parentAllTypeParameters.Count + CurrentTypeParameters.Count]; + all_type_parameters = new TypeParameters (names.Length); + all_type_parameters.Add (parentAllTypeParameters); + + parent_offset = all_type_parameters.Count; + for (int i = 0; i < parent_offset; ++i) + names[i] = all_type_parameters[i].MemberName.Name; + + } else { + names = new string[CurrentTypeParameters.Count]; + } + + for (int i = 0; i < CurrentTypeParameters.Count; ++i) { + if (all_type_parameters != null) + all_type_parameters.Add (MemberName.TypeParameters[i]); + + var name = CurrentTypeParameters[i].MemberName.Name; + names[parent_offset + i] = name; + for (int ii = 0; ii < parent_offset + i; ++ii) { + if (names[ii] != name) + continue; + + var tp = CurrentTypeParameters[i]; + var conflict = all_type_parameters[ii]; + + tp.WarningParentNameConflict (conflict); + } + } + + if (all_type_parameters == null) + all_type_parameters = CurrentTypeParameters; + + return names; + } + + + public SourceMethodBuilder CreateMethodSymbolEntry () + { + if (Module.DeclaringAssembly.SymbolWriter == null) + return null; + + var source_file = GetCompilationSourceFile (); + if (source_file == null) + return null; + + return new SourceMethodBuilder (source_file.SymbolUnitEntry); + } + // // Creates a proxy base method call inside this container for hoisted base member calls // @@ -1129,7 +1327,7 @@ namespace Mono.CSharp } if (proxy_method == null) { - string name = CompilerGeneratedClass.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count); + string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count); var base_parameters = new Parameter[method.Parameters.Count]; for (int i = 0; i < base_parameters.Length; ++i) { var base_param = method.Parameters.FixedParameters[i]; @@ -1144,7 +1342,6 @@ namespace Mono.CSharp cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve (); } - GenericMethod generic_method; MemberName member_name; TypeArguments targs = null; if (method.IsGeneric) { @@ -1152,30 +1349,31 @@ namespace Mono.CSharp // Copy all base generic method type parameters info // var hoisted_tparams = method.GenericDefinition.TypeParameters; - var type_params = new TypeParameter[hoisted_tparams.Length]; + var tparams = new TypeParameters (); + targs = new TypeArguments (); - targs.Arguments = new TypeSpec[type_params.Length]; - for (int i = 0; i < type_params.Length; ++i) { + targs.Arguments = new TypeSpec[hoisted_tparams.Length]; + for (int i = 0; i < hoisted_tparams.Length; ++i) { var tp = hoisted_tparams[i]; - targs.Add (new TypeParameterName (tp.Name, null, Location)); + tparams.Add (new TypeParameter (tp, null, new MemberName (tp.Name, Location), null)); + + targs.Add (new SimpleName (tp.Name, Location)); targs.Arguments[i] = tp; - type_params[i] = new TypeParameter (tp, this, null, new MemberName (tp.Name), null); } - member_name = new MemberName (name, targs, Location); - generic_method = new GenericMethod (NamespaceEntry, this, member_name, type_params, - new TypeExpression (method.ReturnType, Location), cloned_params); + member_name = new MemberName (name, tparams, Location); } else { member_name = new MemberName (name); - generic_method = null; } // Compiler generated proxy - proxy_method = new Method (this, generic_method, new TypeExpression (method.ReturnType, Location), + proxy_method = new Method (this, new TypeExpression (method.ReturnType, Location), Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN, member_name, cloned_params, null); - var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location); + var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) { + IsCompilerGenerated = true + }; var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location); mg.InstanceExpression = new BaseThis (method.DeclaringType, Location); @@ -1193,7 +1391,7 @@ namespace Mono.CSharp block.AddStatement (statement); proxy_method.Block = block; - methods.Add (proxy_method); + members.Add (proxy_method); proxy_method.Define (); hoisted_base_call_proxies.Add (method, proxy_method); @@ -1202,11 +1400,55 @@ namespace Mono.CSharp return proxy_method.Spec; } - bool DefineBaseTypes () + protected bool DefineBaseTypes () { iface_exprs = ResolveBaseTypes (out base_type_expr); - if (partial_parts != null) { - iface_exprs = GetNormalPartialBases (); + bool set_base_type; + + if (IsPartialPart) { + set_base_type = false; + + if (base_type_expr != null) { + if (PartialContainer.base_type_expr != null && PartialContainer.base_type != base_type) { + Report.SymbolRelatedToPreviousError (base_type_expr.Location, ""); + Report.Error (263, Location, + "Partial declarations of `{0}' must not specify different base classes", + GetSignatureForError ()); + } else { + PartialContainer.base_type_expr = base_type_expr; + PartialContainer.base_type = base_type; + set_base_type = true; + } + } + + if (iface_exprs != null) { + if (PartialContainer.iface_exprs == null) + PartialContainer.iface_exprs = iface_exprs; + else { + var ifaces = new List (PartialContainer.iface_exprs); + foreach (var iface_partial in iface_exprs) { + if (ifaces.Contains (iface_partial)) + continue; + + ifaces.Add (iface_partial); + } + + PartialContainer.iface_exprs = ifaces.ToArray (); + } + } + + PartialContainer.members.AddRange (members); + if (containers != null) { + if (PartialContainer.containers == null) + PartialContainer.containers = new List (); + + PartialContainer.containers.AddRange (containers); + } + + members_defined = members_defined_ok = true; + caching_flags |= Flags.CloseTypeCreated; + } else { + set_base_type = true; } var cycle = CheckRecursiveDefinition (this); @@ -1242,7 +1484,7 @@ namespace Mono.CSharp var compiled_iface = iface_type.MemberDefinition as Interface; if (compiled_iface != null) { // TODO: Need DefineBaseType only - compiled_iface.DefineType (); + compiled_iface.DefineContainer (); } if (iface_type.Interfaces != null) { @@ -1265,60 +1507,48 @@ namespace Mono.CSharp return true; } - if (base_type != null) { - spec.BaseType = base_type; + if (set_base_type) { + if (base_type != null) { + spec.BaseType = base_type; - // Set base type after type creation - TypeBuilder.SetParent (base_type.GetMetaInfo ()); - } else { - TypeBuilder.SetParent (null); + // Set base type after type creation + TypeBuilder.SetParent (base_type.GetMetaInfo ()); + } else { + TypeBuilder.SetParent (null); + } } return true; } - public virtual void DefineConstants () + public override void PrepareEmit () { - if (constants != null) { - foreach (Const c in constants) { - c.DefineValue (); - } - } + if ((caching_flags & Flags.CloseTypeCreated) != 0) + return; - if (instance_constructors != null) { - foreach (MethodCore m in instance_constructors) { - var p = m.ParameterInfo; - if (!p.IsEmpty) { - p.ResolveDefaultValues (m); - } - } - } + foreach (var member in members) { + var pm = member as IParametersMember; + if (pm != null) { - if (methods != null) { - foreach (MethodCore m in methods) { - var p = m.ParameterInfo; - if (!p.IsEmpty) { - p.ResolveDefaultValues (m); - } - } - } + var p = pm.Parameters; + if (p.IsEmpty) + continue; - if (indexers != null) { - foreach (Indexer i in indexers) { - i.ParameterInfo.ResolveDefaultValues (i); + ((ParametersCompiled) p).ResolveDefaultValues (member); } - } - if (types != null) { - foreach (var t in types) - t.DefineConstants (); + var c = member as Const; + if (c != null) + c.DefineValue (); } + + base.PrepareEmit (); } // // Defines the type in the appropriate ModuleBuilder or TypeBuilder. // - public bool CreateType () + public override bool CreateContainer () { if (TypeBuilder != null) return !error; @@ -1326,76 +1556,26 @@ namespace Mono.CSharp if (error) return false; - if (!CreateTypeBuilder ()) { - error = true; - return false; - } - - if (partial_parts != null) { - foreach (TypeContainer part in partial_parts) { - part.spec = spec; - part.current_type = current_type; - part.TypeBuilder = TypeBuilder; - } - } - - if (Types != null) { - foreach (TypeContainer tc in Types) { - tc.CreateType (); + if (IsPartialPart) { + spec = PartialContainer.spec; + TypeBuilder = PartialContainer.TypeBuilder; + all_tp_builders = PartialContainer.all_tp_builders; + all_type_parameters = PartialContainer.all_type_parameters; + } else { + if (!CreateTypeBuilder ()) { + error = true; + return false; } } - return true; - } - - public override void DefineType () - { - if (error) - return; - if (type_defined) - return; - - type_defined = true; - - // TODO: Driver resolves only first level of namespace, do the rest here for now - if (IsTopLevel && (ModFlags & Modifiers.COMPILER_GENERATED) == 0) { - NamespaceEntry.Resolve (); - } - - if (!DefineBaseTypes ()) { - error = true; - return; - } - - if (!DefineNestedTypes ()) { - error = true; - return; - } + return base.CreateContainer (); } - public override void SetParameterInfo (List constraints_list) + protected override void DoDefineContainer () { - base.SetParameterInfo (constraints_list); - - if (PartialContainer.CurrentTypeParameters == null || PartialContainer == this) - return; - - TypeParameter[] tc_names = PartialContainer.CurrentTypeParameters; - for (int i = 0; i < tc_names.Length; ++i) { - if (tc_names [i].Name != type_params [i].Name) { - Report.SymbolRelatedToPreviousError (PartialContainer.Location, ""); - Report.Error (264, Location, "Partial declarations of `{0}' must have the same type parameter names in the same order", - GetSignatureForError ()); - break; - } + DefineBaseTypes (); - if (tc_names [i].Variance != type_params [i].Variance) { - Report.SymbolRelatedToPreviousError (PartialContainer.Location, ""); - Report.Error (1067, Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers", - GetSignatureForError ()); - break; - } - } + DoResolveTypeParameters (); } // @@ -1420,75 +1600,50 @@ namespace Mono.CSharp current_type = null; } - void UpdateTypeParameterConstraints (TypeContainer part) + void UpdateTypeParameterConstraints (TypeDefinition part) { - TypeParameter[] current_params = type_params; - for (int i = 0; i < current_params.Length; i++) { - if (current_params [i].AddPartialConstraints (part, part.type_params [i])) + for (int i = 0; i < CurrentTypeParameters.Count; i++) { + if (CurrentTypeParameters[i].AddPartialConstraints (part, part.MemberName.TypeParameters[i])) continue; Report.SymbolRelatedToPreviousError (Location, ""); Report.Error (265, part.Location, "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'", - GetSignatureForError (), current_params [i].GetSignatureForError ()); + GetSignatureForError (), CurrentTypeParameters[i].GetSignatureForError ()); } } - public bool ResolveTypeParameters () + public override void RemoveContainer (TypeContainer cont) { - if (!DoResolveTypeParameters ()) - return false; - - if (types != null) { - foreach (var type in types) - if (!type.ResolveTypeParameters ()) - return false; - } - - if (compiler_generated != null) { - foreach (CompilerGeneratedClass c in compiler_generated) - if (!c.ResolveTypeParameters ()) - return false; - } - - return true; + base.RemoveContainer (cont); + Members.Remove (cont); + Cache.Remove (cont.Basename); } protected virtual bool DoResolveTypeParameters () { - if (CurrentTypeParameters == null) + var tparams = CurrentTypeParameters; + if (tparams == null) return true; - if (PartialContainer != this) - throw new InternalErrorException (); - var base_context = new BaseContext (this); - foreach (TypeParameter type_param in CurrentTypeParameters) { - if (!type_param.ResolveConstraints (base_context)) { + for (int i = 0; i < tparams.Count; ++i) { + var tp = tparams[i]; + + if (!tp.ResolveConstraints (base_context)) { error = true; return false; } } - if (partial_parts != null) { - foreach (TypeContainer part in partial_parts) - UpdateTypeParameterConstraints (part); - } - - return true; - } - - protected virtual bool DefineNestedTypes () - { - if (Types != null) { - foreach (TypeContainer tc in Types) - tc.DefineType (); + if (IsPartialPart) { + PartialContainer.UpdateTypeParameterConstraints (this); } return true; } - TypeSpec CheckRecursiveDefinition (TypeContainer tc) + TypeSpec CheckRecursiveDefinition (TypeDefinition tc) { if (InTransit != null) return spec; @@ -1496,7 +1651,7 @@ namespace Mono.CSharp InTransit = tc; if (base_type != null) { - var ptc = base_type.MemberDefinition as TypeContainer; + var ptc = base_type.MemberDefinition as TypeDefinition; if (ptc != null && ptc.CheckRecursiveDefinition (this) != null) return base_type; } @@ -1530,16 +1685,15 @@ namespace Mono.CSharp members_defined_ok = DoDefineMembers (); members_defined = true; - if (types != null) { - foreach (var nested in types) - nested.Define (); - } + base.Define (); return members_defined_ok; } protected virtual bool DoDefineMembers () { + Debug.Assert (!IsPartialPart); + if (iface_exprs != null) { foreach (var iface_type in iface_exprs) { if (iface_type == null) @@ -1596,7 +1750,7 @@ namespace Mono.CSharp if (obsolete_attr != null && !IsObsolete) AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), base_type_expr.Location, Report); - if (IsGeneric && base_type.IsAttribute) { + if (IsGenericOrParentIsGeneric && base_type.IsAttribute) { Report.Error (698, base_type_expr.Location, "A generic type cannot derive from `{0}' because it is an attribute class", base_type.GetSignatureForError ()); @@ -1620,37 +1774,57 @@ namespace Mono.CSharp } } - DefineContainerMembers (constants); - DefineContainerMembers (fields); - if (Kind == MemberKind.Struct || Kind == MemberKind.Class) { pending = PendingImplementation.GetPendingImplementations (this); + } - if (requires_delayed_unmanagedtype_check) { - requires_delayed_unmanagedtype_check = false; - foreach (FieldBase f in fields) { - if (f.MemberType != null && f.MemberType.IsPointer) - TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location); - } + var count = members.Count; + for (int i = 0; i < count; ++i) { + var mc = members[i] as InterfaceMemberBase; + if (mc == null || !mc.IsExplicitImpl) + continue; + + try { + mc.Define (); + } catch (Exception e) { + throw new InternalErrorException (mc, e); + } + } + + for (int i = 0; i < count; ++i) { + var mc = members[i] as InterfaceMemberBase; + if (mc != null && mc.IsExplicitImpl) + continue; + + if (members[i] is TypeContainer) + continue; + + try { + members[i].Define (); + } catch (Exception e) { + throw new InternalErrorException (members[i], e); } } - - // - // Constructors are not in the defined_names array - // - DefineContainerMembers (instance_constructors); - - DefineContainerMembers (events); - DefineContainerMembers (ordered_explicit_member_list); - DefineContainerMembers (ordered_member_list); - if (operators != null) { - DefineContainerMembers (operators); + if (HasOperators) { CheckPairedOperators (); } + if (requires_delayed_unmanagedtype_check) { + requires_delayed_unmanagedtype_check = false; + foreach (var member in members) { + var f = member as Field; + if (f != null && f.MemberType != null && f.MemberType.IsPointer) + TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location); + } + } + ComputeIndexerName(); - CheckEqualsAndGetHashCode(); + + if (HasEquals && !HasGetHashCode) { + Report.Warning (659, 3, Location, + "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ()); + } if (Kind == MemberKind.Interface && iface_exprs != null) { MemberCache.RemoveHiddenMembers (spec); @@ -1659,212 +1833,157 @@ namespace Mono.CSharp return true; } - protected virtual void DefineContainerMembers (System.Collections.IList mcal) // IList - { - if (mcal != null) { - for (int i = 0; i < mcal.Count; ++i) { - MemberCore mc = (MemberCore) mcal[i]; - try { - mc.Define (); - } catch (Exception e) { - throw new InternalErrorException (mc, e); - } - } - } - } - - protected virtual void ComputeIndexerName () + void ComputeIndexerName () { + var indexers = MemberCache.FindMembers (spec, MemberCache.IndexerNameAlias, true); if (indexers == null) return; string class_indexer_name = null; // - // If there's both an explicit and an implicit interface implementation, the - // explicit one actually implements the interface while the other one is just - // a normal indexer. See bug #37714. + // Check normal indexers for consistent name, explicit interface implementation + // indexers are ignored // - - // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers - foreach (Indexer i in indexers) { - if (i.InterfaceType != null) { - if (seen_normal_indexers) - throw new Exception ("Internal Error: 'Indexers' array not sorted properly."); + foreach (var indexer in indexers) { + // + // FindMembers can return unfiltered full hierarchy names + // + if (indexer.DeclaringType != spec) continue; - } - seen_normal_indexers = true; + has_normal_indexers = true; if (class_indexer_name == null) { - class_indexer_name = i.ShortName; + indexer_name = class_indexer_name = indexer.Name; continue; } - if (i.ShortName != class_indexer_name) - Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type"); + if (indexer.Name != class_indexer_name) + Report.Error (668, ((Indexer)indexer.MemberDefinition).Location, + "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type"); } - - if (class_indexer_name != null) - indexer_name = class_indexer_name; } void EmitIndexerName () { - if (!seen_normal_indexers) + if (!has_normal_indexers) return; var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get (); - if (ctor == null) - return; - - var encoder = new AttributeEncoder (); - encoder.Encode (GetAttributeDefaultMember ()); - encoder.EncodeEmptyNamedArguments (); - - TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); - } - - protected virtual void CheckEqualsAndGetHashCode () - { - if (methods == null) - return; - - if (HasEquals && !HasGetHashCode) { - Report.Warning (659, 3, this.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", this.GetSignatureForError ()); - } - } - - // Indicated whether container has StructLayout attribute set Explicit - public bool HasExplicitLayout { - get { return (caching_flags & Flags.HasExplicitLayout) != 0; } - set { caching_flags |= Flags.HasExplicitLayout; } - } - - public bool HasStructLayout { - get { return (caching_flags & Flags.HasStructLayout) != 0; } - set { caching_flags |= Flags.HasStructLayout; } - } - - public MemberCache MemberCache { - get { - return spec.MemberCache; - } - } - - void CheckMemberUsage (List al, string member_type) - { - if (al == null) + if (ctor == null) return; - foreach (MemberCore mc in al) { - if ((mc.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) - continue; - - if ((mc.ModFlags & Modifiers.PARTIAL) != 0) - continue; + var encoder = new AttributeEncoder (); + encoder.Encode (GetAttributeDefaultMember ()); + encoder.EncodeEmptyNamedArguments (); - if (!mc.IsUsed && (mc.caching_flags & Flags.Excluded) == 0) { - Report.Warning (169, 3, mc.Location, "The private {0} `{1}' is never used", member_type, mc.GetSignatureForError ()); - } - } + TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); } - public virtual void VerifyMembers () + public override void VerifyMembers () { // // Check for internal or private fields that were never assigned // - if (Report.WarningLevel >= 3) { - if (Compiler.Settings.EnhancedWarnings) { - CheckMemberUsage (properties, "property"); - CheckMemberUsage (methods, "method"); - CheckMemberUsage (constants, "constant"); - } - - if (fields != null){ - bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly (); - foreach (FieldBase f in fields) { - if ((f.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) { - if (is_type_exposed) - continue; - - f.SetIsUsed (); - } - - if (!f.IsUsed){ - if ((f.caching_flags & Flags.IsAssigned) == 0) - Report.Warning (169, 3, f.Location, "The private field `{0}' is never used", f.GetSignatureForError ()); - else { - Report.Warning (414, 3, f.Location, "The private field `{0}' is assigned but its value is never used", - f.GetSignatureForError ()); - } - continue; - } - - if ((f.caching_flags & Flags.IsAssigned) != 0) - continue; - + if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) { + bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly (); + foreach (var member in members) { + if (member is Event) { // - // Only report 649 on level 4 + // An event can be assigned from same class only, so we can report + // this warning for all accessibility modes // - if (Report.WarningLevel < 4) - continue; + if (!member.IsUsed) + Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ()); - // - // Don't be pendatic over serializable attributes - // - if (f.OptAttributes != null || PartialContainer.HasStructLayout) + continue; + } + + if ((member.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) { + if (is_type_exposed) continue; - - Constant c = New.Constantify (f.MemberType, f.Location); - string value; - if (c != null) { - value = c.GetValueAsLiteral (); - } else if (TypeSpec.IsReferenceType (f.MemberType)) { - value = "null"; - } else { - // Ignore this warning for struct value fields (they are always initialized) - if (f.MemberType.IsStruct) - continue; - value = null; + member.SetIsUsed (); + } + + var f = member as Field; + if (f == null) + continue; + + if (!member.IsUsed) { + if ((member.caching_flags & Flags.IsAssigned) == 0) { + Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ()); + } else { + Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used", + member.GetSignatureForError ()); } + continue; + } + + if ((f.caching_flags & Flags.IsAssigned) != 0) + continue; + + // + // Only report 649 on level 4 + // + if (Compiler.Settings.WarningLevel < 4) + continue; - if (value != null) - value = " `" + value + "'"; + // + // Don't be pedantic when type requires specific layout + // + if (f.OptAttributes != null || PartialContainer.HasStructLayout) + continue; - Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}", - f.GetSignatureForError (), value); + Constant c = New.Constantify (f.MemberType, f.Location); + string value; + if (c != null) { + value = c.GetValueAsLiteral (); + } else if (TypeSpec.IsReferenceType (f.MemberType)) { + value = "null"; + } else { + value = null; } + + if (value != null) + value = " `" + value + "'"; + + Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}", + f.GetSignatureForError (), value); } } + + base.VerifyMembers (); } public override void Emit () { - if (!IsTopLevel) { - MemberSpec candidate; - bool overrides = false; - var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides); - if (conflict_symbol == null && candidate == null) { - if ((ModFlags & Modifiers.NEW) != 0) - Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", - GetSignatureForError ()); - } else { - if ((ModFlags & Modifiers.NEW) == 0) { - if (candidate == null) - candidate = conflict_symbol; + if (OptAttributes != null) + OptAttributes.Emit (); - Report.SymbolRelatedToPreviousError (candidate); - Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended", - GetSignatureForError (), candidate.GetSignatureForError ()); + if (!IsCompilerGenerated) { + if (!IsTopLevel) { + MemberSpec candidate; + bool overrides = false; + var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides); + if (conflict_symbol == null && candidate == null) { + if ((ModFlags & Modifiers.NEW) != 0) + Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", + GetSignatureForError ()); + } else { + if ((ModFlags & Modifiers.NEW) == 0) { + if (candidate == null) + candidate = conflict_symbol; + + Report.SymbolRelatedToPreviousError (candidate); + Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended", + GetSignatureForError (), candidate.GetSignatureForError ()); + } } } - } - // Run constraints check on all possible generic types - if ((ModFlags & Modifiers.COMPILER_GENERATED) == 0) { + // Run constraints check on all possible generic types if (base_type != null && base_type_expr != null) { ConstraintChecker.Check (this, base_type, base_type_expr.Location); } @@ -1883,7 +2002,7 @@ namespace Mono.CSharp int current_starts_index = CurrentTypeParametersStartIndex; for (int i = 0; i < all_tp_builders.Length; i++) { if (i < current_starts_index) { - TypeParameters[i].EmitConstraints (all_tp_builders [i]); + all_type_parameters[i].EmitConstraints (all_tp_builders [i]); } else { var tp = CurrentTypeParameters [i - current_starts_index]; tp.CheckGenericConstraints (!IsObsolete); @@ -1901,113 +2020,44 @@ namespace Mono.CSharp #endif base.Emit (); - } - - // TODO: move to ClassOrStruct - void EmitConstructors () - { - if (instance_constructors == null) - return; - - if (spec.IsAttribute && IsExposedFromAssembly () && Compiler.Settings.VerifyClsCompliance && IsClsComplianceRequired ()) { - bool has_compliant_args = false; - foreach (Constructor c in instance_constructors) { - try { - c.Emit (); - } - catch (Exception e) { - throw new InternalErrorException (c, e); - } + for (int i = 0; i < members.Count; i++) + members[i].Emit (); - if (has_compliant_args) - continue; + EmitIndexerName (); + CheckAttributeClsCompliance (); - has_compliant_args = c.HasCompliantArgs; - } - if (!has_compliant_args) - Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ()); - } else { - foreach (Constructor c in instance_constructors) { - try { - c.Emit (); - } - catch (Exception e) { - throw new InternalErrorException (c, e); - } - } - } + if (pending != null) + pending.VerifyPendingMethods (); } - /// - /// Emits the code, this step is performed after all - /// the types, enumerations, constructors - /// - public virtual void EmitType () + + void CheckAttributeClsCompliance () { - if ((caching_flags & Flags.CloseTypeCreated) != 0) + if (!spec.IsAttribute || !IsExposedFromAssembly () || !Compiler.Settings.VerifyClsCompliance || !IsClsComplianceRequired ()) return; - if (OptAttributes != null) - OptAttributes.Emit (); - - Emit (); - - EmitConstructors (); - - if (constants != null) - foreach (Const con in constants) - con.Emit (); - - if (default_static_constructor != null) - default_static_constructor.Emit (); - - if (operators != null) - foreach (Operator o in operators) - o.Emit (); - - if (properties != null) - foreach (Property p in properties) - p.Emit (); - - if (indexers != null) { - foreach (Indexer indx in indexers) - indx.Emit (); - EmitIndexerName (); - } - - if (events != null){ - foreach (Event e in Events) - e.Emit (); - } - - if (methods != null) { - for (int i = 0; i < methods.Count; ++i) - ((MethodOrOperator) methods [i]).Emit (); - } - - if (fields != null) - foreach (FieldBase f in fields) - f.Emit (); + foreach (var m in members) { + var c = m as Constructor; + if (c == null) + continue; - if (types != null) { - foreach (TypeContainer t in types) - t.EmitType (); + if (c.HasCompliantArgs) + return; } - if (pending != null) - pending.VerifyPendingMethods (); + Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ()); + } - if (Report.Errors > 0) + public sealed override void EmitContainer () + { + if ((caching_flags & Flags.CloseTypeCreated) != 0) return; - if (compiler_generated != null) { - for (int i = 0; i < compiler_generated.Count; ++i) - compiler_generated [i].EmitType (); - } + Emit (); } - public virtual void CloseType () + public override void CloseContainer () { if ((caching_flags & Flags.CloseTypeCreated) != 0) return; @@ -2016,7 +2066,7 @@ namespace Mono.CSharp if (spec.BaseType != null) { var btype = spec.BaseType.MemberDefinition as TypeContainer; if (btype != null) { - btype.CloseType (); + btype.CloseContainer (); if ((caching_flags & Flags.CloseTypeCreated) != 0) return; @@ -2026,38 +2076,19 @@ namespace Mono.CSharp try { caching_flags |= Flags.CloseTypeCreated; TypeBuilder.CreateType (); - } catch (TypeLoadException){ + } catch (TypeLoadException) { // // This is fine, the code still created the type // -// Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name); -// Console.WriteLine (e.Message); } catch (Exception e) { throw new InternalErrorException (this, e); } - - if (Types != null){ - foreach (TypeContainer tc in Types) - tc.CloseType (); - } - if (compiler_generated != null) - foreach (CompilerGeneratedClass c in compiler_generated) - c.CloseType (); + base.CloseContainer (); - types = null; + containers = null; initialized_fields = null; initialized_static_fields = null; - constants = null; - ordered_explicit_member_list = null; - ordered_member_list = null; - methods = null; - events = null; - indexers = null; - operators = null; - compiler_generated = null; - default_constructor = null; - default_static_constructor = null; type_bases = null; OptAttributes = null; } @@ -2138,18 +2169,11 @@ namespace Mono.CSharp return ok; } - public Constructor DefaultStaticConstructor { - get { return default_static_constructor; } - } - protected override bool VerifyClsCompliance () { if (!base.VerifyClsCompliance ()) return false; - // Check this name against other containers - NamespaceEntry.NS.VerifyClsCompliance (); - // Check all container names for user classes if (Kind != MemberKind.Delegate) MemberCache.VerifyClsCompliance (Definition, Report); @@ -2203,11 +2227,24 @@ namespace Mono.CSharp return false; } + public override bool IsClsComplianceRequired () + { + if (IsPartialPart) + return PartialContainer.IsClsComplianceRequired (); + + return base.IsClsComplianceRequired (); + } + bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly) { return Module.DeclaringAssembly == assembly; } + public virtual bool IsUnmanagedType () + { + return false; + } + public void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache) { throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ()); @@ -2229,9 +2266,9 @@ namespace Mono.CSharp e = null; if (arity == 0) { - TypeParameter[] tp = CurrentTypeParameters; + var tp = CurrentTypeParameters; if (tp != null) { - TypeParameter tparam = TypeParameter.FindTypeParameter (tp, name); + TypeParameter tparam = tp.Find (name); if (tparam != null) e = new TypeParameterExpr (tparam, Location.Null); } @@ -2242,15 +2279,8 @@ namespace Mono.CSharp if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility)) e = new TypeExpression (t, Location.Null); - else if (Parent != null) { + else { e = Parent.LookupNamespaceOrType (name, arity, mode, loc); - } else { - int errors = Report.Errors; - - e = NamespaceEntry.LookupNamespaceOrType (name, arity, mode, loc); - - if (errors != Report.Errors) - return e; } } @@ -2263,21 +2293,12 @@ namespace Mono.CSharp TypeSpec LookupNestedTypeInHierarchy (string name, int arity) { - // TODO: GenericMethod only - if (PartialContainer == null) - return null; - // Has any nested type // Does not work, because base type can have //if (PartialContainer.Types == null) // return null; var container = PartialContainer.CurrentType; - - // Is not Root container - if (container == null) - return null; - return MemberCache.FindNestedType (container, name, arity); } @@ -2291,6 +2312,16 @@ namespace Mono.CSharp cached_method |= CachedMethods.GetHashCode; } + public override void WriteDebugSymbol (MonoSymbolFile file) + { + if (IsPartialPart) + return; + + foreach (var m in members) { + m.WriteDebugSymbol (file); + } + } + /// /// Method container contains Equals method /// @@ -2326,24 +2357,43 @@ namespace Mono.CSharp } } - public abstract class ClassOrStruct : TypeContainer + public abstract class ClassOrStruct : TypeDefinition { + public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed; + SecurityType declarative_security; - public ClassOrStruct (NamespaceContainer ns, DeclSpace parent, - MemberName name, Attributes attrs, MemberKind kind) - : base (ns, parent, name, attrs, kind) + public ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind) + : base (parent, name, attrs, kind) { } - protected override bool AddToContainer (MemberCore symbol, string name) + protected override TypeAttributes TypeAttr { + get { + TypeAttributes ta = base.TypeAttr; + if (!has_static_constructor) + ta |= TypeAttributes.BeforeFieldInit; + + if (Kind == MemberKind.Class) { + ta |= TypeAttributes.AutoLayout | TypeAttributes.Class; + if (IsStatic) + ta |= StaticClassAttribute; + } else { + ta |= TypeAttributes.SequentialLayout; + } + + return ta; + } + } + + public override void AddNameToContainer (MemberCore symbol, string name) { if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) { if (symbol is TypeParameter) { Report.Error (694, symbol.Location, "Type parameter `{0}' has same name as containing type, or method", symbol.GetSignatureForError ()); - return false; + return; } InterfaceMemberBase imb = symbol as InterfaceMemberBase; @@ -2351,30 +2401,11 @@ namespace Mono.CSharp Report.SymbolRelatedToPreviousError (this); Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type", symbol.GetSignatureForError ()); - return false; - } - } - - return base.AddToContainer (symbol, name); - } - - public override void VerifyMembers () - { - base.VerifyMembers (); - - if ((events != null) && Report.WarningLevel >= 3) { - foreach (Event e in events){ - // Note: The event can be assigned from same class only, so we can report - // this warning for all accessibility modes - if ((e.caching_flags & Flags.IsUsed) == 0) - Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ()); + return; } } - if (types != null) { - foreach (var t in types) - t.VerifyMembers (); - } + base.AddNameToContainer (symbol, name); } public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) @@ -2401,7 +2432,7 @@ namespace Mono.CSharp /// /// Defines the default constructors /// - protected void DefineDefaultConstructor (bool is_static) + protected Constructor DefineDefaultConstructor (bool is_static) { // The default instance constructor is public // If the class is abstract, the default constructor is protected @@ -2414,13 +2445,15 @@ namespace Mono.CSharp mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC; } - Constructor c = new Constructor (this, MemberName.Name, mods, - null, ParametersCompiled.EmptyReadOnlyParameters, - new GeneratedBaseInitializer (Location), - Location); + var c = new Constructor (this, MemberName.Name, mods, null, ParametersCompiled.EmptyReadOnlyParameters, Location); + c.Initializer = new GeneratedBaseInitializer (Location); - AddConstructor (c); - c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location); + AddConstructor (c, true); + c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location) { + IsCompilerGenerated = true + }; + + return c; } protected override bool DoDefineMembers () @@ -2429,17 +2462,14 @@ namespace Mono.CSharp base.DoDefineMembers (); - if (default_static_constructor != null) - default_static_constructor.Define (); - return true; } public override void Emit () { - if (default_static_constructor == null && PartialContainer.HasStaticFieldInitializer) { - DefineDefaultConstructor (true); - default_static_constructor.Define (); + if (!has_static_constructor && HasStaticFieldInitializer) { + var c = DefineDefaultConstructor (true); + c.Define (); } base.Emit (); @@ -2454,35 +2484,11 @@ namespace Mono.CSharp } } } - - public override ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity) - { - DeclSpace top_level = Parent; - if (top_level != null) { - var methods = NamespaceEntry.NS.LookupExtensionMethod (this, extensionType, name, arity); - if (methods != null) { - return new ExtensionMethodCandidates (methods, NamespaceEntry, NamespaceEntry.NS) { - HasUninspectedMembers = true - }; - } - } - - return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity); - } - - protected override TypeAttributes TypeAttr { - get { - if (default_static_constructor == null) - return base.TypeAttr | TypeAttributes.BeforeFieldInit; - - return base.TypeAttr; - } - } } - // TODO: should be sealed - public class Class : ClassOrStruct { + public sealed class Class : ClassOrStruct + { const Modifiers AllowedModifiers = Modifiers.NEW | Modifiers.PUBLIC | @@ -2494,13 +2500,10 @@ namespace Mono.CSharp Modifiers.STATIC | Modifiers.UNSAFE; - public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed; - - public Class (NamespaceContainer ns, DeclSpace parent, MemberName name, Modifiers mod, - Attributes attrs) - : base (ns, parent, name, attrs, MemberKind.Class) + public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs) + : base (parent, name, attrs, MemberKind.Class) { - var accmods = (Parent == null || Parent.Parent == null) ? Modifiers.INTERNAL : Modifiers.PRIVATE; + var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE; this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report); spec = new TypeSpec (Kind, null, this, null, ModFlags); } @@ -2510,12 +2513,14 @@ namespace Mono.CSharp visitor.Visit (this); } - public override void AddBasesForPart (DeclSpace part, List bases) + public override void AddBasesForPart (List bases) { - if (part.Name == "System.Object") - Report.Error (537, part.Location, + var pmn = MemberName; + if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null) + Report.Error (537, Location, "The class System.Object cannot have a base class or implement an interface."); - base.AddBasesForPart (part, bases); + + base.AddBasesForPart (bases); } public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) @@ -2541,7 +2546,7 @@ namespace Mono.CSharp return; } - if (a.Type.IsConditionallyExcluded (Compiler, Location)) + if (a.Type.IsConditionallyExcluded (this, Location)) return; base.ApplyAttributeBuilder (a, ctor, cdata, pa); @@ -2553,46 +2558,6 @@ namespace Mono.CSharp } } - protected override void DefineContainerMembers (System.Collections.IList list) - { - if (list == null) - return; - - if (!IsStatic) { - base.DefineContainerMembers (list); - return; - } - - foreach (MemberCore m in list) { - if (m is Operator) { - Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ()); - continue; - } - - if (m is Destructor) { - Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ()); - continue; - } - - if (m is Indexer) { - Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ()); - continue; - } - - if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate) - continue; - - if (m is Constructor) { - Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ()); - continue; - } - - Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ()); - } - - base.DefineContainerMembers (list); - } - protected override bool DoDefineMembers () { if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) { @@ -2603,8 +2568,37 @@ namespace Mono.CSharp Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ()); } - if (InstanceConstructors == null && !IsStatic) - DefineDefaultConstructor (false); + if (IsStatic) { + foreach (var m in Members) { + if (m is Operator) { + Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ()); + continue; + } + + if (m is Destructor) { + Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ()); + continue; + } + + if (m is Indexer) { + Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ()); + continue; + } + + if ((m.ModFlags & Modifiers.STATIC) != 0 || m is TypeContainer) + continue; + + if (m is Constructor) { + Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ()); + continue; + } + + Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ()); + } + } else { + if (!PartialContainer.HasInstanceConstructor) + DefineDefaultConstructor (false); + } return base.DoDefineMembers (); } @@ -2699,23 +2693,10 @@ namespace Mono.CSharp caching_flags |= Flags.Excluded; return conditions; } - - // - // FIXME: How do we deal with the user specifying a different - // layout? - // - protected override TypeAttributes TypeAttr { - get { - TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class; - if (IsStatic) - ta |= StaticClassAttribute; - return ta; - } - } } - public sealed class Struct : ClassOrStruct { - + public sealed class Struct : ClassOrStruct + { bool is_unmanaged, has_unmanaged_check_done; bool InTransit; @@ -2730,11 +2711,10 @@ namespace Mono.CSharp Modifiers.UNSAFE | Modifiers.PRIVATE; - public Struct (NamespaceContainer ns, DeclSpace parent, MemberName name, - Modifiers mod, Attributes attrs) - : base (ns, parent, name, attrs, MemberKind.Struct) + public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs) + : base (parent, name, attrs, MemberKind.Struct) { - var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE; + var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE; this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ; spec = new TypeSpec (Kind, null, this, null, ModFlags); } @@ -2759,13 +2739,13 @@ namespace Mono.CSharp // set CharSet, its value has to be propagated to compiler generated // fixed types // - if (a.Type == pa.StructLayout && Fields != null) { + if (a.Type == pa.StructLayout) { var value = a.GetNamedValue ("CharSet"); if (value == null) return; - for (int i = 0; i < Fields.Count; ++i) { - FixedField ff = Fields [i] as FixedField; + for (int i = 0; i < Members.Count; ++i) { + FixedField ff = Members [i] as FixedField; if (ff == null) continue; @@ -2774,16 +2754,17 @@ namespace Mono.CSharp } } - bool CheckStructCycles (Struct s) + bool CheckStructCycles () { - if (s.Fields == null) - return true; - - if (s.InTransit) + if (InTransit) return false; - s.InTransit = true; - foreach (FieldBase field in s.Fields) { + InTransit = true; + foreach (var member in Members) { + var field = member as Field; + if (field == null) + continue; + TypeSpec ftype = field.Spec.MemberType; if (!ftype.IsStruct) continue; @@ -2803,7 +2784,7 @@ namespace Mono.CSharp // // Static fields of exactly same type are allowed // - if (field.IsStatic && ftype == s.CurrentType) + if (field.IsStatic && ftype == CurrentType) continue; if (!CheckFieldTypeCycle (ftype)) { @@ -2814,22 +2795,22 @@ namespace Mono.CSharp } } - s.InTransit = false; + InTransit = false; return true; } - bool CheckFieldTypeCycle (TypeSpec ts) + static bool CheckFieldTypeCycle (TypeSpec ts) { var fts = ts.MemberDefinition as Struct; if (fts == null) return true; - return CheckStructCycles (fts); + return fts.CheckStructCycles (); } public override void Emit () { - CheckStructCycles (this); + CheckStructCycles (); base.Emit (); } @@ -2842,15 +2823,20 @@ namespace Mono.CSharp if (requires_delayed_unmanagedtype_check) return true; - if (Parent != null && Parent.IsGeneric) { + var parent_def = Parent.PartialContainer; + if (parent_def != null && parent_def.IsGenericOrParentIsGeneric) { has_unmanaged_check_done = true; return false; } - if (fields != null) { + if (first_nonstatic_field != null) { requires_delayed_unmanagedtype_check = true; - foreach (FieldBase f in fields) { + foreach (var member in Members) { + var f = member as Field; + if (f == null) + continue; + if (f.IsStatic) continue; @@ -2882,16 +2868,6 @@ namespace Mono.CSharp return ifaces; } - protected override TypeAttributes TypeAttr { - get { - const TypeAttributes DefaultTypeAttributes = - TypeAttributes.SequentialLayout | - TypeAttributes.Sealed; - - return base.TypeAttr | DefaultTypeAttributes; - } - } - public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression) { if ((field.ModFlags & Modifiers.STATIC) == 0) { @@ -2907,7 +2883,7 @@ namespace Mono.CSharp /// /// Interfaces /// - public sealed class Interface : TypeContainer { + public sealed class Interface : TypeDefinition { /// /// Modifiers allowed in a class declaration @@ -2920,11 +2896,10 @@ namespace Mono.CSharp Modifiers.UNSAFE | Modifiers.PRIVATE; - public Interface (NamespaceContainer ns, DeclSpace parent, MemberName name, Modifiers mod, - Attributes attrs) - : base (ns, parent, name, attrs, MemberKind.Interface) + public Interface (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs) + : base (parent, name, attrs, MemberKind.Interface) { - var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE; + var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE; this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report); spec = new TypeSpec (Kind, null, this, null, ModFlags); @@ -3034,7 +3009,7 @@ namespace Mono.CSharp // // If true, this is an explicit interface implementation // - public bool IsExplicitImpl; + public readonly bool IsExplicitImpl; protected bool is_external_implementation; @@ -3051,14 +3026,11 @@ namespace Mono.CSharp readonly Modifiers explicit_mod_flags; public MethodAttributes flags; - public InterfaceMemberBase (DeclSpace parent, GenericMethod generic, - FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, - MemberName name, Attributes attrs) - : base (parent, generic, type, mod, allowed_mod, Modifiers.PRIVATE, - name, attrs) + public InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs) + : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs) { - IsInterface = parent.PartialContainer.Kind == MemberKind.Interface; - IsExplicitImpl = (MemberName.Left != null); + IsInterface = parent.Kind == MemberKind.Interface; + IsExplicitImpl = (MemberName.ExplicitInterface != null); explicit_mod_flags = mod; } @@ -3281,7 +3253,7 @@ namespace Mono.CSharp } if (IsExplicitImpl) { - InterfaceType = MemberName.Left.GetTypeExpression ().ResolveAsType (Parent); + InterfaceType = MemberName.ExplicitInterface.ResolveAsType (Parent); if (InterfaceType == null) return false; @@ -3349,7 +3321,7 @@ namespace Mono.CSharp { // for extern static method must be specified either DllImport attribute or MethodImplAttribute. // We are more strict than csc and report this as an error because SRE does not allow emit that - if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation) { + if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) { if (this is Constructor) { Report.Warning (824, 1, Location, "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ()); @@ -3418,7 +3390,6 @@ namespace Mono.CSharp // public string ShortName { get { return MemberName.Name; } - set { SetMemberName (new MemberName (MemberName.Left, value, Location)); } } // @@ -3453,44 +3424,35 @@ namespace Mono.CSharp return Parent.GetSignatureForDocumentation () + "." + ShortName; } - protected override bool VerifyClsCompliance () - { - if (!base.VerifyClsCompliance ()) { - return false; - } - - if (GenericMethod != null) - GenericMethod.VerifyClsCompliance (); - - return true; - } - public override bool IsUsed { get { return IsExplicitImpl || base.IsUsed; } } + public override void SetConstraints (List constraints_list) + { + if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) { + Report.Error (460, Location, + "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods", + GetSignatureForError ()); + } + + base.SetConstraints (constraints_list); + } } public abstract class MemberBase : MemberCore { protected FullNamedExpression type_expr; protected TypeSpec member_type; + public new TypeDefinition Parent; - public readonly DeclSpace ds; - public readonly GenericMethod GenericMethod; - - protected MemberBase (DeclSpace parent, GenericMethod generic, - FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, - MemberName name, Attributes attrs) + protected MemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs) : base (parent, name, attrs) { - this.ds = generic != null ? generic : (DeclSpace) parent; + this.Parent = parent; this.type_expr = type; ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report); - GenericMethod = generic; - if (GenericMethod != null) - GenericMethod.ModFlags = ModFlags; } #region Properties @@ -3603,7 +3565,7 @@ namespace Mono.CSharp public override string GetSignatureForDocumentation () { - return Parent.Name + "." + Name; + return Parent.GetSignatureForDocumentation () + "." + MemberName.Basename; } protected virtual bool ResolveMemberType ()