2007-02-23 Nagappan A <anagappan@novell.com>
[mono.git] / mcs / tools / monop / outline.cs
index d35c93463cbbba93233d5cfb65f6327971d8ce89..35f1e4fb99cd3079c853e593c2ab50486c7607e3 100644 (file)
@@ -67,7 +67,7 @@ public class Outline {
                o.Write (GetTypeKind (t));
                o.Write (" ");
                
-               Type [] interfaces = (Type []) Comparer.Sort (t.GetInterfaces ());
+               Type [] interfaces = (Type []) Comparer.Sort (TypeGetInterfaces (t, options.DeclaredOnly));
                Type parent = t.BaseType;
 
                if (t.IsSubclassOf (typeof (System.MulticastDelegate))) {
@@ -80,12 +80,13 @@ public class Outline {
                        o.Write (GetTypeName (t));
                        o.Write (" (");
                        OutlineParams (method.GetParameters ());
-                       o.WriteLine (")");
+                       o.Write (")");
 
 #if NET_2_0
                        WriteGenericConstraints (t.GetGenericArguments ());
 #endif                 
-
+       
+                       o.WriteLine (";"); 
                        return;
                }
                
@@ -226,7 +227,7 @@ public class Outline {
                
                foreach (EventInfo ei in Comparer.Sort (t.GetEvents (DefaultFlags))) {
                        
-                       if (! ShowMember (ei.GetAddMethod ()))
+                       if (! ShowMember (ei.GetAddMethod (true)))
                                continue;
                        
                        if (first)
@@ -281,7 +282,7 @@ public class Outline {
 
        void OutlineEvent (EventInfo ei)
        {
-               MethodBase accessor = ei.GetAddMethod ();
+               MethodBase accessor = ei.GetAddMethod (true);
                
                o.Write (GetMethodVisibility (accessor));
                o.Write ("event ");
@@ -360,10 +361,20 @@ public class Outline {
        
        void OutlineMethod (MethodInfo mi)
        {
-               o.Write (GetMethodVisibility (mi));
-               o.Write (GetMethodModifiers  (mi));
-               o.Write (FormatType (mi.ReturnType));
-               o.Write (" ");
+               if (MethodIsExplicitIfaceImpl (mi)) {
+                       o.Write (FormatType (mi.ReturnType));
+                       o.Write (" ");
+                       // MSFT has no way to get the method that we are overriding
+                       // from the interface. this would allow us to pretty print
+                       // the type name (and be more correct if there compiler
+                       // were to do some strange naming thing).
+               } else {
+                       o.Write (GetMethodVisibility (mi));
+                       o.Write (GetMethodModifiers  (mi));
+                       o.Write (FormatType (mi.ReturnType));
+                       o.Write (" ");
+               }
+
                o.Write (mi.Name);
 #if NET_2_0
                o.Write (FormatGenericParams (mi.GetGenericArguments ()));
@@ -424,15 +435,23 @@ public class Outline {
                if (fi.IsPrivate)  o.Write ("private ");
                if (fi.IsAssembly) o.Write ("internal ");
                if (fi.IsLiteral)  o.Write ("const ");
+               else if (fi.IsStatic) o.Write ("static ");
                if (fi.IsInitOnly) o.Write ("readonly ");
 
                o.Write (FormatType (fi.FieldType));
                o.Write (" ");
                o.Write (fi.Name);
-               if (fi.IsLiteral)
-               {
+               if (fi.IsLiteral) { 
+                       object v = fi.GetValue (this);
+
+                       // TODO: Escape values here
                        o.Write (" = ");
-                       o.Write (fi.GetValue (this));
+                       if (v is char)
+                               o.Write ("'{0}'", v);
+                       else if (v is string)
+                               o.Write ("\"{0}\"", v);
+                       else
+                               o.Write (fi.GetValue (this));
                }
                o.Write (";");
        }
@@ -455,13 +474,38 @@ public class Outline {
        {
                if (method.IsStatic)
                        return "static ";
-       
+
+               if (method.IsFinal) {
+                       // This will happen if you have
+                       // class X : IA {
+                       //   public void A () {}
+                       //   static void Main () {}
+                       // }
+                       // interface IA {
+                       //   void A ();
+                       // }
+                       //
+                       // A needs to be virtual (the CLR requires
+                       // methods implementing an iface be virtual),
+                       // but can not be inherited. It also can not
+                       // be inherited. In C# this is represented
+                       // with no special modifiers
+
+                       if (method.IsVirtual)
+                               return null;
+                       return "sealed ";
+               }
+               
                // all interface methods are "virtual" but we don't say that in c#
-               if (method.IsVirtual && !method.DeclaringType.IsInterface)
+               if (method.IsVirtual && !method.DeclaringType.IsInterface) {
+                       if (method.IsAbstract)
+                               return "abstract ";
+
                        return ((method.Attributes & MethodAttributes.NewSlot) != 0) ?
                                "virtual " :
-                               "override ";
-               
+                               "override ";    
+               }
+                               
                return null;
        }
 
@@ -515,6 +559,8 @@ public class Outline {
                return sb.ToString ();
        }
        
+       // TODO: fine tune this so that our output is less verbose. We need to figure
+       // out a way to do this while not making things confusing.
        string FormatType (Type t)
        {
                string type = GetFullName (t);
@@ -559,7 +605,17 @@ public class Outline {
        
                if (type.LastIndexOf(".") == 6)
                        return type.Substring(7);
-               
+
+               //
+               // If the namespace of the type is the namespace of what
+               // we are printing (or is a member of one if its children
+               // don't print it. This basically means that in C# we would
+               // automatically get the namespace imported by virtue of the
+               // namespace {} block.
+               //      
+               if (this.t.Namespace.StartsWith (t.Namespace + ".") || t.Namespace == this.t.Namespace)
+                       return type.Substring (t.Namespace.Length + 1);
+       
                return type;
        }
 
@@ -639,13 +695,12 @@ public class Outline {
 
                foreach (Type t in args) {
                        bool first = true;
-                       Type[] ifaces = t.GetInterfaces();
-                       ifaces = Array.FindAll<Type> (ifaces, delegate (Type iface) { return !iface.IsAssignableFrom (t.BaseType); });
+                       Type[] ifaces = TypeGetInterfaces (t, true);
                        
                        GenericParameterAttributes attrs = t.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
                        GenericParameterAttributes [] interesting = {
                                GenericParameterAttributes.ReferenceTypeConstraint,
-                               GenericParameterAttributes.ValueTypeConstraint,
+                               GenericParameterAttributes.NotNullableValueTypeConstraint,
                                GenericParameterAttributes.DefaultConstructorConstraint
                        };
                        
@@ -680,7 +735,7 @@ public class Outline {
                                case GenericParameterAttributes.ReferenceTypeConstraint:
                                        o.Write ("class");
                                        break;
-                               case GenericParameterAttributes.ValueTypeConstraint:
+                               case GenericParameterAttributes.NotNullableValueTypeConstraint:
                                        o.Write ("struct");
                                        break;
                                case GenericParameterAttributes.DefaultConstructorConstraint:
@@ -722,6 +777,26 @@ public class Outline {
                default: return name;
                }
        }
+
+       bool MethodIsExplicitIfaceImpl (MethodBase mb)
+       {
+               if (!(mb.IsFinal && mb.IsVirtual && mb.IsPrivate))
+                       return false;
+               
+               // UGH msft has no way to get the info about what method is
+               // getting overriden. Another reason to use cecil :-)
+               //
+               //MethodInfo mi = mb as MethodInfo;
+               //if (mi == null)
+               //      return false;
+               //
+               //Console.WriteLine (mi.GetBaseDefinition ().DeclaringType);
+               //return mi.GetBaseDefinition ().DeclaringType.IsInterface;
+               
+               // So, we guess that virtual final private methods only come
+               // from ifaces :-)
+               return true;
+       }
        
        bool ShowMember (MemberInfo mi)
        {
@@ -730,6 +805,9 @@ public class Outline {
                
                if (options.ShowPrivate)
                        return true;
+
+               if (options.FilterObsolete && mi.IsDefined (typeof (ObsoleteAttribute), false))
+                       return false;
                
                switch (mi.MemberType) {
                case MemberTypes.Constructor:
@@ -739,6 +817,9 @@ public class Outline {
                        if (mb.IsFamily || mb.IsPublic || mb.IsFamilyOrAssembly)
                                return true;
                        
+                       if (MethodIsExplicitIfaceImpl (mb))
+                               return true;
+                                       
                        return false;
                
                
@@ -769,6 +850,25 @@ public class Outline {
                // What am I !!!
                return true;
        }
+
+       static Type [] TypeGetInterfaces (Type t, bool declonly)
+       {
+               Type [] ifaces = t.GetInterfaces ();
+               if (! declonly)
+                       return ifaces;
+
+               // Handle Object. Also, optimize for no interfaces
+               if (t.BaseType == null || ifaces.Length == 0)
+                       return ifaces;
+
+               ArrayList ar = new ArrayList ();
+
+               foreach (Type i in ifaces)
+                       if (! i.IsAssignableFrom (t.BaseType))
+                               ar.Add (i);
+
+               return (Type []) ar.ToArray (typeof (Type));
+       }
 }
 
 public class Comparer : IComparer  {
@@ -822,9 +922,27 @@ public class Comparer : IComparer  {
        {
                MethodBase aa = (MethodBase) a, bb = (MethodBase) b;
                
-               if (aa.IsStatic == bb.IsStatic)
-                       return CompareMemberInfo (a, b);
-               
+               if (aa.IsStatic == bb.IsStatic) {
+                       int c = CompareMemberInfo (a, b);
+                       if (c != 0)
+                               return c;
+                       ParameterInfo [] ap, bp;
+
+                       //
+                       // Sort overloads by the names of their types
+                       // put methods with fewer params first.
+                       //
+                       
+                       ap = aa.GetParameters ();
+                       bp = bb.GetParameters ();
+                       int n = Math.Min (ap.Length, bp.Length);
+
+                       for (int i = 0; i < n; i ++)
+                               if ((c = CompareType (ap [i].ParameterType, bp [i].ParameterType)) != 0)
+                                       return c;
+
+                       return ap.Length.CompareTo (bp.Length);
+               }
                if (aa.IsStatic)
                        return -1;