**** Merged r36987 from MCS ****
[mono.git] / mcs / gmcs / decl.cs
index 5b5e04b16b288a0925362fc066e1d2185d9d5df9..f3ac24f95594b18fcded3a291f91e515f83e7bb7 100755 (executable)
@@ -7,6 +7,7 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 //
 // TODO: Move the method verification stuff from the class.cs and interface.cs here
 //
@@ -17,6 +18,7 @@ using System.Collections;
 using System.Globalization;
 using System.Reflection.Emit;
 using System.Reflection;
+using System.Xml;
 
 namespace Mono.CSharp {
 
@@ -90,28 +92,11 @@ namespace Mono.CSharp {
                public string GetMethodName ()
                {
                        if (Left != null)
-                               return Left.GetPartialName () + "." + Name;
+                               return Left.GetTypeName () + "." + Name;
                        else
                                return Name;
                }
 
-               ///
-               /// This returns exclusively the name as seen on the source code
-               /// it is not the fully qualifed type after resolution
-               ///
-               public string GetPartialName ()
-               {
-                       string full_name;
-                       if (TypeArguments != null)
-                               full_name = Name + "<" + TypeArguments + ">";
-                       else
-                               full_name = Name;
-                       if (Left != null)
-                               return Left.GetPartialName () + "." + full_name;
-                       else
-                               return full_name;
-               }
-
                public static string MakeName (string name, TypeArguments args)
                {
                        if (args == null)
@@ -228,7 +213,8 @@ namespace Mono.CSharp {
                        }
                }
 
-               public readonly MemberName MemberName;
+                // Is not readonly because of IndexerName attribute
+               public MemberName MemberName;
 
                /// <summary>
                ///   Modifier flags that the user specified in the source code
@@ -242,6 +228,17 @@ namespace Mono.CSharp {
                /// </summary>
                public readonly Location Location;
 
+               /// <summary>
+               ///   XML documentation comment
+               /// </summary>
+               public string DocComment;
+
+               /// <summary>
+               ///   Represents header string for documentation comment 
+               ///   for each member types.
+               /// </summary>
+               public abstract string DocCommentHeader { get; }
+
                [Flags]
                public enum Flags {
                        Obsolete_Undetected = 1,                // Obsolete attribute has not been detected yet
@@ -391,7 +388,7 @@ namespace Mono.CSharp {
                /// <summary>
                /// Returns true when MemberCore is exposed from assembly.
                /// </summary>
-               protected bool IsExposedFromAssembly (DeclSpace ds)
+               public bool IsExposedFromAssembly (DeclSpace ds)
                {
                        if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
                                return false;
@@ -411,7 +408,8 @@ namespace Mono.CSharp {
                bool GetClsCompliantAttributeValue (DeclSpace ds)
                {
                        if (OptAttributes != null) {
-                               Attribute cls_attribute = OptAttributes.GetClsCompliantAttribute (ds.EmitContext);
+                               Attribute cls_attribute = OptAttributes.Search (
+                                       TypeManager.cls_compliant_attribute_type, ds.EmitContext);
                                if (cls_attribute != null) {
                                        caching_flags |= Flags.HasClsCompliantAttribute;
                                        return cls_attribute.GetClsCompliantAttributeValue (ds);
@@ -460,6 +458,34 @@ namespace Mono.CSharp {
 
                protected abstract void VerifyObsoleteAttribute ();
 
+               //
+               // Raised (and passed an XmlElement that contains the comment)
+               // when GenerateDocComment is writing documentation expectedly.
+               //
+               internal virtual void OnGenerateDocComment (DeclSpace ds, XmlElement intermediateNode)
+               {
+               }
+
+               //
+               // Returns a string that represents the signature for this 
+               // member which should be used in XML documentation.
+               //
+               public virtual string GetDocCommentName (DeclSpace ds)
+               {
+                       if (ds == null || this is DeclSpace)
+                               return DocCommentHeader + Name;
+                       else
+                               return String.Concat (DocCommentHeader, ds.Name, ".", Name);
+               }
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal virtual void GenerateDocComment (DeclSpace ds)
+               {
+                       DocUtil.GenerateDocComment (this, ds);
+               }
        }
 
        /// <summary>
@@ -482,7 +508,7 @@ namespace Mono.CSharp {
                ///   currently defining.  We need to lookup members on this
                ///   instead of the TypeBuilder.
                /// </summary>
-               public TypeExpr CurrentType;
+               public Type CurrentType;
 
                //
                // This is the namespace in which this typecontainer
@@ -685,16 +711,6 @@ namespace Mono.CSharp {
                        return type_resolve_ec;
                }
 
-               // <summary>
-               //    Looks up the type, as parsed into the expression `e'.
-               // </summary>
-               [Obsolete ("This method is going away soon")]
-               public Type ResolveType (Expression e, bool silent, Location loc)
-               {
-                       TypeExpr d = ResolveTypeExpr (e, silent, loc);
-                       return d == null ? null : d.Type;
-               }
-
                public Type ResolveNestedType (Type t, Location loc)
                {
                        TypeContainer tc = TypeManager.LookupTypeContainer (t);
@@ -714,8 +730,12 @@ namespace Mono.CSharp {
                                else
                                        args = TypeParameters;
 
-                               ConstructedType ctype = new ConstructedType (t, args, loc);
-                               t = ctype.ResolveType (ec);
+                               TypeExpr ctype = new ConstructedType (t, args, loc);
+                               ctype = ctype.ResolveAsTypeTerminal (ec);
+                               if (ctype == null)
+                                       return null;
+
+                               t = ctype.Type;
                        }
 
                        return t;
@@ -725,7 +745,7 @@ namespace Mono.CSharp {
                //    Resolves the expression `e' for a type, and will recursively define
                //    types.  This should only be used for resolving base types.
                // </summary>
-               public TypeExpr ResolveTypeExpr (Expression e, bool silent, Location loc)
+               public TypeExpr ResolveTypeExpr (Expression e, Location loc)
                {
                        if (type_resolve_ec == null)
                                type_resolve_ec = GetTypeResolveEmitContext (Parent, loc);
@@ -735,7 +755,7 @@ namespace Mono.CSharp {
                        else
                                type_resolve_ec.ContainerType = TypeBuilder;
 
-                       return e.ResolveAsTypeTerminal (type_resolve_ec, silent);
+                       return e.ResolveAsTypeTerminal (type_resolve_ec);
                }
                
                public bool CheckAccessLevel (Type check_type) 
@@ -756,7 +776,7 @@ namespace Mono.CSharp {
                                return true; // FIXME
                        
                        TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask;
-
+                       
                        //
                        // Broken Microsoft runtime, return public for arrays, no matter what 
                        // the accessibility is for their underlying class, and they return 
@@ -771,14 +791,14 @@ namespace Mono.CSharp {
 
                        case TypeAttributes.NotPublic:
 
-                               if (TypeBuilder == null)
+                               if (TypeBuilder == null)
                                        // FIXME: TypeBuilder will be null when invoked by Class.GetNormalBases().
                                        //        However, this is invoked again later -- so safe to return true.
                                        //        May also be null when resolving top-level attributes.
-                                       return true;
-                               //
-                               // This test should probably use the declaringtype.
-                               //
+                                       return true;
+                               //
+                               // This test should probably use the declaringtype.
+                               //
                                return check_type.Assembly == TypeBuilder.Assembly;
 
                        case TypeAttributes.NestedPublic:
@@ -1200,7 +1220,7 @@ namespace Mono.CSharp {
                        caching_flags &= ~Flags.HasCompliantAttribute_Undetected;
 
                        if (OptAttributes != null) {
-                               Attribute cls_attribute = OptAttributes.GetClsCompliantAttribute (ec);
+                               Attribute cls_attribute = OptAttributes.Search (TypeManager.cls_compliant_attribute_type, ec);
                                if (cls_attribute != null) {
                                        caching_flags |= Flags.HasClsCompliantAttribute;
                                        if (cls_attribute.GetClsCompliantAttributeValue (this)) {
@@ -1390,17 +1410,15 @@ namespace Mono.CSharp {
                        get { return Name; }
                }
 
-               TypeExpr IAlias.Type
+               TypeExpr IAlias.ResolveAsType (EmitContext ec)
                {
-                       get {
-                               if (TypeBuilder == null)
-                                       throw new InvalidOperationException ();
-
-                               if (CurrentType != null)
-                                       return CurrentType;
+                       if (TypeBuilder == null)
+                               throw new InvalidOperationException ();
 
+                       if (CurrentType != null)
+                               return new TypeExpression (CurrentType, Location);
+                       else
                                return new TypeExpression (TypeBuilder, Location);
-                       }
                }
 
                public override string[] ValidAttributeTargets {
@@ -1585,7 +1603,7 @@ namespace Mono.CSharp {
                ///   This is used when creating the member cache for a class to get all
                ///   members from the parent class.
                /// </summary>
-               IMemberContainer ParentContainer {
+               MemberCache ParentCache {
                        get;
                }
 
@@ -1636,31 +1654,21 @@ namespace Mono.CSharp {
                public readonly IMemberContainer Container;
                protected Hashtable member_hash;
                protected Hashtable method_hash;
-               
+
                /// <summary>
                ///   Create a new MemberCache for the given IMemberContainer `container'.
                /// </summary>
-               public MemberCache (IMemberContainer container, bool setup_inherited_interfaces)
+               public MemberCache (IMemberContainer container)
                {
                        this.Container = container;
 
                        Timer.IncrementCounter (CounterType.MemberCache);
                        Timer.StartTimer (TimerType.CacheInit);
 
-                       
-
                        // If we have a parent class (we have a parent class unless we're
                        // TypeManager.object_type), we deep-copy its MemberCache here.
-                       if (Container.IsInterface) {
-                               MemberCache parent;
-                               
-                               if (Container.ParentContainer != null)
-                                       parent = Container.ParentContainer.MemberCache;
-                               else
-                                       parent = null;
-                               member_hash = SetupCacheForInterface (parent, setup_inherited_interfaces);
-                       } else if (Container.ParentContainer != null)
-                               member_hash = SetupCache (Container.ParentContainer.MemberCache);
+                       if (Container.ParentCache != null)
+                               member_hash = SetupCache (Container.ParentCache);
                        else
                                member_hash = new Hashtable ();
 
@@ -1678,37 +1686,55 @@ namespace Mono.CSharp {
                        Timer.StopTimer (TimerType.CacheInit);
                }
 
+               public MemberCache (Type[] ifaces)
+               {
+                       //
+                       // The members of this cache all belong to other caches.  
+                       // So, 'Container' will not be used.
+                       //
+                       this.Container = null;
+
+                       member_hash = new Hashtable ();
+                       if (ifaces == null)
+                               return;
+
+                       foreach (Type itype in ifaces)
+                               AddCacheContents (TypeManager.LookupMemberCache (itype));
+               }
+
                /// <summary>
                ///   Bootstrap this member cache by doing a deep-copy of our parent.
                /// </summary>
                Hashtable SetupCache (MemberCache parent)
                {
                        Hashtable hash = new Hashtable ();
+
                        if (parent == null)
                                return hash;
 
                        IDictionaryEnumerator it = parent.member_hash.GetEnumerator ();
                        while (it.MoveNext ()) {
                                hash [it.Key] = ((ArrayList) it.Value).Clone ();
-                       }
+                        }
                                 
                        return hash;
                }
 
-
                /// <summary>
-               ///   Add the contents of `new_hash' to `hash'.
+               ///   Add the contents of `cache' to the member_hash.
                /// </summary>
-               void AddHashtable (Hashtable hash, MemberCache cache)
+               void AddCacheContents (MemberCache cache)
                {
-                       Hashtable new_hash = cache.member_hash;
-                       IDictionaryEnumerator it = new_hash.GetEnumerator ();
+                       IDictionaryEnumerator it = cache.member_hash.GetEnumerator ();
                        while (it.MoveNext ()) {
-                               ArrayList list = (ArrayList) hash [it.Key];
+                               ArrayList list = (ArrayList) member_hash [it.Key];
                                if (list == null)
-                                       hash [it.Key] = list = new ArrayList ();
+                                       member_hash [it.Key] = list = new ArrayList ();
+
+                               ArrayList entries = (ArrayList) it.Value;
+                               for (int i = entries.Count-1; i >= 0; i--) {
+                                       CacheEntry entry = (CacheEntry) entries [i];
 
-                               foreach (CacheEntry entry in (ArrayList) it.Value) {
                                        if (entry.Container != cache.Container)
                                                break;
                                        list.Add (entry);
@@ -1716,32 +1742,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               /// <summary>
-               ///   Bootstrap the member cache for an interface type.
-               ///   Type.GetMembers() won't return any inherited members for interface types,
-               ///   so we need to do this manually.  Interfaces also inherit from System.Object.
-               /// </summary>
-               Hashtable SetupCacheForInterface (MemberCache parent, bool deep_setup)
-               {
-                       Hashtable hash = SetupCache (parent);
-
-                       if (!deep_setup)
-                               return hash;
-
-                       Type [] ifaces = TypeManager.GetInterfaces (Container.Type);
-
-                       foreach (Type itype in ifaces) {
-                               IMemberContainer iface_container =
-                                       TypeManager.LookupMemberContainer (itype);
-
-                               MemberCache iface_cache = iface_container.MemberCache;
-
-                               AddHashtable (hash, iface_cache);
-                       }
-
-                       return hash;
-               }
-
                /// <summary>
                ///   Add all members from class `container' to the cache.
                /// </summary>
@@ -1750,8 +1750,8 @@ namespace Mono.CSharp {
                        // We need to call AddMembers() with a single member type at a time
                        // to get the member type part of CacheEntry.EntryType right.
                        if (!container.IsInterface) {
-                               AddMembers (MemberTypes.Constructor, container);
-                               AddMembers (MemberTypes.Field, container);
+                       AddMembers (MemberTypes.Constructor, container);
+                       AddMembers (MemberTypes.Field, container);
                        }
                        AddMembers (MemberTypes.Method, container);
                        AddMembers (MemberTypes.Property, container);
@@ -1904,7 +1904,7 @@ namespace Mono.CSharp {
                ///   number to speed up the searching process.
                /// </summary>
                [Flags]
-               protected internal enum EntryType {
+               protected enum EntryType {
                        None            = 0x000,
 
                        Instance        = 0x001,
@@ -1927,7 +1927,7 @@ namespace Mono.CSharp {
                        MaskType        = Constructor|Event|Field|Method|Property|NestedType
                }
 
-               protected internal struct CacheEntry {
+               protected struct CacheEntry {
                        public readonly IMemberContainer Container;
                        public readonly EntryType EntryType;
                        public readonly MemberInfo Member;
@@ -1939,6 +1939,12 @@ namespace Mono.CSharp {
                                this.Member = member;
                                this.EntryType = GetEntryType (mt, bf);
                        }
+
+                       public override string ToString ()
+                       {
+                               return String.Format ("CacheEntry ({0}:{1}:{2})", Container.Name,
+                                                     EntryType, Member);
+                       }
                }
 
                /// <summary>