2005-12-23 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / mcs / doc.cs
index 1f0173dce7159a2d4be9a9cd08e8e28d15046990..8f0d14fbce42aa7dc0b6a3a2be63be8d826aacae 100644 (file)
@@ -333,8 +333,7 @@ namespace Mono.CSharp {
                        // no need to detect warning 419 here
                        return FindDocumentedMember (mc, parent,
                                identifier.Substring (index + 1),
-                               Type.EmptyTypes,
-                               ds, out warn, cref, false, null) as Type;
+                               null, ds, out warn, cref, false, null).Member as Type;
                }
 
                private static MemberInfo [] empty_member_infos =
@@ -384,22 +383,9 @@ namespace Mono.CSharp {
                {
                        if (ml == null)
                                return empty_member_infos;
-                       if (type.IsInterface)
-                               return ml;
 
                        ArrayList al = new ArrayList (ml.Length);
                        for (int i = 0; i < ml.Length; i++) {
-                               // Interface methods which are returned
-                               // from the filter must exist in the 
-                               // target type (if there is only a 
-                               // private implementation, then the 
-                               // filter should not return it.)
-                               // This filtering is required to 
-                               // deambiguate results.
-                               //
-                               // It is common to properties, so check it here.
-                               if (ml [i].DeclaringType.IsInterface)
-                                       continue;
                                MethodBase mx = ml [i] as MethodBase;
                                PropertyInfo px = ml [i] as PropertyInfo;
                                if (mx != null || px != null) {
@@ -430,28 +416,59 @@ namespace Mono.CSharp {
                        return al.ToArray (typeof (MemberInfo)) as MemberInfo [];
                }
 
+               struct FoundMember
+               {
+                       public static FoundMember Empty = new FoundMember (true);
+
+                       public bool IsEmpty;
+                       public readonly MemberInfo Member;
+                       public readonly Type Type;
+
+                       public FoundMember (bool regardlessOfThisValueItsEmpty)
+                       {
+                               IsEmpty = true;
+                               Member = null;
+                               Type = null;
+                       }
+
+                       public FoundMember (Type foundType, MemberInfo member)
+                       {
+                               IsEmpty = false;
+                               Type = foundType;
+                               Member = member;
+                       }
+               }
+
                //
                // Returns a MemberInfo that is referenced in XML documentation
                // (by "see" or "seealso" elements).
                //
-               private static MemberInfo FindDocumentedMember (MemberCore mc,
+               private static FoundMember FindDocumentedMember (MemberCore mc,
                        Type type, string memberName, Type [] paramList, 
                        DeclSpace ds, out int warningType, string cref,
                        bool warn419, string nameForError)
                {
+                       for (; type != null; type = type.DeclaringType) {
+                               MemberInfo mi = FindDocumentedMemberNoNest (
+                                       mc, type, memberName, paramList, ds,
+                                       out warningType, cref, warn419,
+                                       nameForError);
+                               if (mi != null)
+                                       return new FoundMember (type, mi);
+                       }
                        warningType = 0;
-                       MethodSignature msig = new MethodSignature (memberName, null, paramList);
-                       MemberInfo [] mis = FindMethodBase (type, 
-                               BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
-                               msig);
+                       return FoundMember.Empty;
+               }
 
-                       if (warn419 && mis.Length > 0) {
-                               if (IsAmbiguous (mis))
-                                       Report419 (mc, nameForError, mis);
-                               return mis [0];
-                       }
+               private static MemberInfo FindDocumentedMemberNoNest (
+                       MemberCore mc, Type type, string memberName,
+                       Type [] paramList, DeclSpace ds, out int warningType, 
+                       string cref, bool warn419, string nameForError)
+               {
+                       warningType = 0;
+                       MemberInfo [] mis;
 
-                       if (paramList.Length == 0) {
+                       if (paramList == null) {
                                // search for fields/events etc.
                                mis = TypeManager.MemberLookup (type, null,
                                        type, MemberTypes.All,
@@ -465,6 +482,17 @@ namespace Mono.CSharp {
                                return mis [0];
                        }
 
+                       MethodSignature msig = new MethodSignature (memberName, null, paramList);
+                       mis = FindMethodBase (type, 
+                               BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
+                               msig);
+
+                       if (warn419 && mis.Length > 0) {
+                               if (IsAmbiguous (mis))
+                                       Report419 (mc, nameForError, mis);
+                               return mis [0];
+                       }
+
                        // search for operators (whose parameters exactly
                        // matches with the list) and possibly report CS1581.
                        string oper = null;
@@ -620,7 +648,7 @@ namespace Mono.CSharp {
                        }
                        else {
                                name = signature;
-                               parameters = String.Empty;
+                               parameters = null;
                        }
                        Normalize (mc, ref name);
 
@@ -644,8 +672,12 @@ namespace Mono.CSharp {
                        }
 
                        // check if parameters are valid
-                       Type [] parameterTypes = Type.EmptyTypes;
-                       if (parameters.Length > 0) {
+                       Type [] parameterTypes;
+                       if (parameters == null)
+                               parameterTypes = null;
+                       else if (parameters.Length == 0)
+                               parameterTypes = Type.EmptyTypes;
+                       else {
                                string [] paramList = parameters.Split (',');
                                ArrayList plist = new ArrayList ();
                                for (int i = 0; i < paramList.Length; i++) {
@@ -666,19 +698,13 @@ namespace Mono.CSharp {
                        if (type != null
                                // delegate must not be referenced with args
                                && (!type.IsSubclassOf (typeof (System.Delegate))
-                               || parameterTypes.Length == 0)) {
+                               || parameterTypes == null)) {
                                string result = type.FullName.Replace ("+", ".")
                                        + (bracePos < 0 ? String.Empty : signature.Substring (bracePos));
                                xref.SetAttribute ("cref", "T:" + result);
                                return; // a type
                        }
 
-                       // don't use identifier here. System[] is not alloed.
-                       if (RootNamespace.Global.IsNamespace (name)) {
-                               xref.SetAttribute ("cref", "N:" + name);
-                               return; // a namespace
-                       }
-
                        int period = name.LastIndexOf ('.');
                        if (period > 0) {
                                string typeName = name.Substring (0, period);
@@ -687,26 +713,47 @@ namespace Mono.CSharp {
                                type = FindDocumentedType (mc, typeName, ds, cref);
                                int warnResult;
                                if (type != null) {
-                                       MemberInfo mi = FindDocumentedMember (mc, type, memberName, parameterTypes, ds, out warnResult, cref, true, name);
+                                       FoundMember fm = FindDocumentedMember (mc, type, memberName, parameterTypes, ds, out warnResult, cref, true, name);
                                        if (warnResult > 0)
                                                return;
-                                       if (mi != null) {
-                                               xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + type.FullName.Replace ("+", ".") + "." + memberName + GetParametersFormatted (mi));
+                                       if (!fm.IsEmpty) {
+                                               MemberInfo mi = fm.Member;
+                                               // we cannot use 'type' directly
+                                               // to get its name, since mi
+                                               // could be from DeclaringType
+                                               // for nested types.
+                                               xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + fm.Type.FullName.Replace ("+", ".") + "." + memberName + GetParametersFormatted (mi));
                                                return; // a member of a type
                                        }
                                }
                        }
                        else {
                                int warnResult;
-                               MemberInfo mi = FindDocumentedMember (mc, ds.TypeBuilder, name, parameterTypes, ds, out warnResult, cref, true, name);
+                               FoundMember fm = FindDocumentedMember (mc, ds.TypeBuilder, name, parameterTypes, ds, out warnResult, cref, true, name);
                                if (warnResult > 0)
                                        return;
-                               if (mi != null) {
-                                       xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + ds.TypeBuilder.FullName.Replace ("+", ".") + "." + name + GetParametersFormatted (mi));
+                               if (!fm.IsEmpty) {
+                                       MemberInfo mi = fm.Member;
+                                       // we cannot use 'type' directly
+                                       // to get its name, since mi
+                                       // could be from DeclaringType
+                                       // for nested types.
+                                       xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + fm.Type.FullName.Replace ("+", ".") + "." + name + GetParametersFormatted (mi));
                                        return; // local member name
                                }
                        }
 
+                       // It still might be part of namespace name.
+                       Namespace ns = ds.NamespaceEntry.NS.GetNamespace (name, false);
+                       if (ns != null) {
+                               xref.SetAttribute ("cref", "N:" + ns.FullName);
+                               return; // a namespace
+                       }
+                       if (RootNamespace.Global.IsNamespace (name)) {
+                               xref.SetAttribute ("cref", "N:" + name);
+                               return; // a namespace
+                       }
+
                        Report.Warning (1574, 1, mc.Location, "XML comment on `{0}' has cref attribute `{1}' that could not be resolved",
                                mc.GetSignatureForError (), cref);