X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Froottypes.cs;h=48f2b266b3b7637a15fdbf0c15a8dfebc27f70c6;hb=f574f7b447e29c6f083fcad4e6dc5f89d3cb4b4d;hp=55c65df9a85262fcb0734948596de5cc03a13951;hpb=40b3c2f2889ea217e1c978224298a1bf843b0b17;p=mono.git diff --git a/mcs/mcs/roottypes.cs b/mcs/mcs/roottypes.cs index 55c65df9a85..48f2b266b3b 100644 --- a/mcs/mcs/roottypes.cs +++ b/mcs/mcs/roottypes.cs @@ -8,6 +8,7 @@ // // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) // Copyright 2003-2008 Novell, Inc. +// Copyright 2011 Xamarin Inc // using System; @@ -28,7 +29,7 @@ namespace Mono.CSharp // // Module (top-level type) container // - public class ModuleContainer : TypeContainer + public sealed class ModuleContainer : TypeContainer { #if STATIC // @@ -36,7 +37,7 @@ namespace Mono.CSharp // sealed class StaticDataContainer : CompilerGeneratedClass { - Dictionary size_types; + readonly Dictionary size_types; new int fields; public StaticDataContainer (ModuleContainer module) @@ -63,28 +64,14 @@ namespace Mono.CSharp // DefineInitializedData because it creates public type, // and its name is not unique among modules // - size_type = new Struct (null, this, new MemberName ("$ArrayType=" + data.Length, Location), Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, null); + size_type = new Struct (null, this, new MemberName ("$ArrayType=" + data.Length, loc), Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, null); size_type.CreateType (); size_type.DefineType (); size_types.Add (data.Length, size_type); - var pa = Module.PredefinedAttributes.StructLayout; - if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.short_type)) { - var argsEncoded = new AttributeEncoder (); - argsEncoded.Encode ((short) LayoutKind.Explicit); - - var field_size = pa.GetField ("Size", TypeManager.int32_type, Location); - var pack = pa.GetField ("Pack", TypeManager.int32_type, Location); - if (field_size != null) { - argsEncoded.EncodeNamedArguments ( - new[] { field_size, pack }, - new[] { new IntConstant ((int) data.Length, Location), new IntConstant (1, Location) } - ); - } - - pa.EmitAttribute (size_type.TypeBuilder, argsEncoded); - } + // It has to work even if StructLayoutAttribute does not exist + size_type.TypeBuilder.__SetLayout (1, data.Length); } var name = "$field-" + fields.ToString ("X"); @@ -119,13 +106,19 @@ namespace Mono.CSharp public CharSet? DefaultCharSet; public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass; - Dictionary> anonymous_types; - Dictionary arrays; + readonly Dictionary> anonymous_types; + readonly Dictionary array_types; + readonly Dictionary pointer_types; + readonly Dictionary reference_types; + readonly Dictionary attrs_cache; + + // Used for unique namespaces/types during parsing + Dictionary defined_type_containers; AssemblyDefinition assembly; readonly CompilerContext context; readonly RootNamespace global_ns; - Dictionary alias_ns; + readonly Dictionary alias_ns; ModuleBuilder builder; @@ -133,6 +126,7 @@ namespace Mono.CSharp PredefinedAttributes predefined_attributes; PredefinedTypes predefined_types; + PredefinedMembers predefined_members; static readonly string[] attribute_targets = new string[] { "assembly", "module" }; @@ -147,14 +141,28 @@ namespace Mono.CSharp anonymous_types = new Dictionary> (); global_ns = new GlobalRootNamespace (); alias_ns = new Dictionary (); - arrays = new Dictionary (); + array_types = new Dictionary (); + pointer_types = new Dictionary (); + reference_types = new Dictionary (); + attrs_cache = new Dictionary (); + + defined_type_containers = new Dictionary (); } #region Properties - public Dictionary ArraysCache { + internal Dictionary ArrayTypesCache { get { - return arrays; + return array_types; + } + } + + // + // Cache for parameter-less attributes + // + internal Dictionary AttributeConstructorCache { + get { + return attrs_cache; } } @@ -182,6 +190,14 @@ namespace Mono.CSharp } } + internal DocumentationBuilder DocumentationBuilder { + get; set; + } + + public Evaluator Evaluator { + get; set; + } + public bool HasDefaultCharSet { get { return DefaultCharSet.HasValue; @@ -197,6 +213,10 @@ namespace Mono.CSharp } } + public bool HasTypesFullyDefined { + get; set; + } + // // Returns module global:: namespace // @@ -212,18 +232,36 @@ namespace Mono.CSharp } } + internal Dictionary PointerTypesCache { + get { + return pointer_types; + } + } + internal PredefinedAttributes PredefinedAttributes { get { return predefined_attributes; } } + internal PredefinedMembers PredefinedMembers { + get { + return predefined_members; + } + } + internal PredefinedTypes PredefinedTypes { get { return predefined_types; } } + internal Dictionary ReferenceTypesCache { + get { + return reference_types; + } + } + public override string[] ValidAttributeTargets { get { return attribute_targets; @@ -232,6 +270,11 @@ namespace Mono.CSharp #endregion + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } + public void AddAnonymousType (AnonymousTypeClass type) { List existing; @@ -244,21 +287,16 @@ namespace Mono.CSharp existing.Add (type); } - public void AddAttributes (List attrs) - { - AddAttributes (attrs, this); - } - - public void AddAttributes (List attrs, IMemberContext context) + public void AddAttribute (Attribute attr, IMemberContext context) { - foreach (Attribute a in attrs) - a.AttachTo (this, context); + attr.AttachTo (this, context); if (attributes == null) { - attributes = new Attributes (attrs); + attributes = new Attributes (attr); return; } - attributes.AddAttributes (attrs); + + attributes.AddAttribute (attr); } public override TypeContainer AddPartial (TypeContainer nextPart) @@ -329,7 +367,7 @@ namespace Mono.CSharp public RootNamespace CreateRootNamespace (string alias) { if (alias == global_ns.Alias) { - NamespaceEntry.Error_GlobalNamespaceRedefined (Location.Null, Report); + RootNamespace.Error_GlobalNamespaceRedefined (Report, Location.Null); return global_ns; } @@ -350,16 +388,25 @@ namespace Mono.CSharp public new void CreateType () { + // Release cache used by parser only + if (Evaluator == null) + defined_type_containers = null; + else + defined_type_containers.Clear (); + foreach (TypeContainer tc in types) tc.CreateType (); } public new void Define () { - InitializePredefinedTypes (); - - foreach (TypeContainer tc in types) - tc.DefineType (); + foreach (TypeContainer tc in types) { + try { + tc.DefineType (); + } catch (Exception e) { + throw new InternalErrorException (tc, e); + } + } foreach (TypeContainer tc in types) tc.ResolveTypeParameters (); @@ -371,6 +418,8 @@ namespace Mono.CSharp throw new InternalErrorException (tc, e); } } + + HasTypesFullyDefined = true; } public override void Emit () @@ -401,6 +450,12 @@ namespace Mono.CSharp c.EmitType (); } + internal override void GenerateDocComment (DocumentationBuilder builder) + { + foreach (var tc in types) + tc.GenerateDocComment (builder); + } + public AnonymousTypeClass GetAnonymousType (IList parameters) { List candidates; @@ -437,6 +492,7 @@ namespace Mono.CSharp { predefined_attributes = new PredefinedAttributes (this); predefined_types = new PredefinedTypes (this); + predefined_members = new PredefinedMembers (this); } public override bool IsClsComplianceRequired () @@ -444,16 +500,58 @@ namespace Mono.CSharp return DeclaringAssembly.IsCLSCompliant; } - protected override bool AddMemberType (TypeContainer ds) + protected override bool AddMemberType (TypeContainer tc) { - if (!AddToContainer (ds, ds.Name)) - return false; - ds.NamespaceEntry.NS.AddType (ds.Definition); - return true; + if (AddTypesContainer (tc)) { + if ((tc.ModFlags & Modifiers.PARTIAL) != 0) + defined_names.Add (tc.Name, tc); + + tc.NamespaceEntry.NS.AddType (this, tc.Definition); + return true; + } + + return false; } - protected override void RemoveMemberType (DeclSpace ds) + public bool AddTypesContainer (ITypesContainer container) { + var mn = container.MemberName; + ITypesContainer found; + if (!defined_type_containers.TryGetValue (mn, out found)) { + defined_type_containers.Add (mn, container); + return true; + } + + if (container is NamespaceContainer && found is NamespaceContainer) + return true; + + var container_tc = container as TypeContainer; + var found_tc = found as TypeContainer; + if (container_tc != null && found_tc != null && container_tc.Kind == found_tc.Kind) { + if ((found_tc.ModFlags & container_tc.ModFlags & Modifiers.PARTIAL) != 0) { + return false; + } + + if (((found_tc.ModFlags | container_tc.ModFlags) & Modifiers.PARTIAL) != 0) { + Report.SymbolRelatedToPreviousError (found_tc); + Error_MissingPartialModifier (container_tc); + return false; + } + } + + string ns = mn.Left != null ? mn.Left.GetSignatureForError () : Module.GlobalRootNamespace.GetSignatureForError (); + mn = new MemberName (mn.Name, mn.TypeArguments, mn.Location); + + Report.SymbolRelatedToPreviousError (found.Location, ""); + Report.Error (101, container.Location, + "The namespace `{0}' already contains a definition for `{1}'", + ns, mn.GetSignatureForError ()); + return false; + } + + protected override void RemoveMemberType (TypeContainer ds) + { + defined_type_containers.Remove (ds.MemberName); ds.NamespaceEntry.NS.RemoveDeclSpace (ds.Basename); base.RemoveMemberType (ds); } @@ -474,11 +572,11 @@ namespace Mono.CSharp } } - class RootDeclSpace : TypeContainer { - public RootDeclSpace (NamespaceEntry ns) + sealed class RootDeclSpace : TypeContainer { + public RootDeclSpace (ModuleContainer module, NamespaceContainer ns) : base (ns, null, MemberName.Null, null, 0) { - PartialContainer = RootContext.ToplevelTypes; + PartialContainer = module; } public override AttributeTargets AttributeTargets { @@ -506,11 +604,21 @@ namespace Mono.CSharp } } + public override void Accept (StructuralVisitor visitor) + { + throw new InternalErrorException ("should not be called"); + } + public override bool IsClsComplianceRequired () { return PartialContainer.IsClsComplianceRequired (); } + public override ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity) + { + return null; + } + public override FullNamedExpression LookupNamespaceAlias (string name) { return NamespaceEntry.LookupNamespaceAlias (name);