Add [Category ("NotWorking")] to failing test.
[mono.git] / mcs / tools / monop / outline.cs
1 //
2 // outline -- support for rendering in monop
3 // Some code stolen from updater.cs in monodoc.
4 //
5 // Authors:
6 //      Ben Maurer (bmaurer@users.sourceforge.net)
7 //
8 // (C) 2004 Ben Maurer
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 #if !NET_2_1
33
34 using System;
35 using System.Reflection;
36 using System.Collections;
37 using System.CodeDom.Compiler;
38 using System.IO;
39 using System.Text;
40
41 namespace Mono.CSharp {
42 public class Outline {
43
44         bool declared_only;
45         bool show_private;
46         bool filter_obsolete;
47         
48         IndentedTextWriter o;
49         Type t;
50         
51         public Outline (Type t, TextWriter output, bool declared_only, bool show_private, bool filter_obsolete)
52         {
53                 this.t = t;
54                 this.o = new IndentedTextWriter (output, "\t");
55                 this.declared_only = declared_only;
56                 this.show_private = show_private;
57                 this.filter_obsolete = filter_obsolete;
58         }
59
60         public void OutlineType ()
61         {
62                 bool first;
63                 
64                 OutlineAttributes ();
65                 o.Write (GetTypeVisibility (t));
66                 
67                 if (t.IsClass && !t.IsSubclassOf (typeof (System.MulticastDelegate))) {
68                         if (t.IsSealed)
69                                 o.Write (t.IsAbstract ? " static" : " sealed");
70                         else if (t.IsAbstract)
71                                 o.Write (" abstract");
72                 }
73                 
74                 o.Write (" ");
75                 o.Write (GetTypeKind (t));
76                 o.Write (" ");
77                 
78                 Type [] interfaces = (Type []) Comparer.Sort (TypeGetInterfaces (t, declared_only));
79                 Type parent = t.BaseType;
80
81                 if (t.IsSubclassOf (typeof (System.MulticastDelegate))) {
82                         MethodInfo method;
83
84                         method = t.GetMethod ("Invoke");
85
86                         o.Write (FormatType (method.ReturnType));
87                         o.Write (" ");
88                         o.Write (GetTypeName (t));
89                         o.Write (" (");
90                         OutlineParams (method.GetParameters ());
91                         o.Write (")");
92
93                         WriteGenericConstraints (t.GetGenericArguments ());
94         
95                         o.WriteLine (";"); 
96                         return;
97                 }
98                 
99                 o.Write (GetTypeName (t));
100                 if (((parent != null && parent != typeof (object) && parent != typeof (ValueType)) || interfaces.Length != 0) && ! t.IsEnum) {
101                         first = true;
102                         o.Write (" : ");
103                         
104                         if (parent != null && parent != typeof (object) && parent != typeof (ValueType)) {
105                                 o.Write (FormatType (parent));
106                                 first = false;
107                         }
108                         
109                         foreach (Type intf in interfaces) {
110                                 if (!first) o.Write (", ");
111                                 first = false;
112                                 
113                                 o.Write (FormatType (intf));
114                         }
115                 }
116
117                 if (t.IsEnum) {
118                         Type underlyingType = System.Enum.GetUnderlyingType (t);
119                         if (underlyingType != typeof (int))
120                                 o.Write (" : {0}", FormatType (underlyingType));
121                 }
122
123                 WriteGenericConstraints (t.GetGenericArguments ());
124
125                 o.WriteLine (" {");
126                 o.Indent++;
127
128                 if (t.IsEnum) {
129                         bool is_first = true;
130                         foreach (FieldInfo fi in t.GetFields (BindingFlags.Public | BindingFlags.Static)) {
131                                 
132                                 if (! is_first)
133                                         o.WriteLine (",");
134                                 is_first = false;
135                                 o.Write (fi.Name);
136                         }
137                         o.WriteLine ();
138                         o.Indent--; o.WriteLine ("}");
139                         return;
140                 }
141                 
142                 first = true;
143                 
144                 foreach (ConstructorInfo ci in t.GetConstructors (DefaultFlags)) {
145                         if (! ShowMember (ci))
146                                 continue;
147                         
148                         if (first)
149                                 o.WriteLine ();
150                         first = false;
151                         
152                         OutlineMemberAttribute (ci);
153                         OutlineConstructor (ci);
154                         
155                         o.WriteLine ();
156                 }
157                 
158
159                 first = true;
160                 
161                 foreach (MethodInfo m in Comparer.Sort (t.GetMethods (DefaultFlags))) {
162                         
163                         if (! ShowMember (m))
164                                 continue;               
165                         
166                         if ((m.Attributes & MethodAttributes.SpecialName) != 0)
167                                 continue;
168                         
169                         if (first)
170                                 o.WriteLine ();
171                         first = false;
172
173                         OutlineMemberAttribute (m);
174                         OutlineMethod (m);
175                         
176                         o.WriteLine ();
177                 }
178                 
179                 first = true;
180                 
181                 foreach (MethodInfo m in t.GetMethods (DefaultFlags)) {
182                         
183                         if (! ShowMember (m))
184                                 continue;
185                         
186                         if ((m.Attributes & MethodAttributes.SpecialName) == 0)
187                                 continue;
188                         if (!(m.Name.StartsWith ("op_")))
189                                 continue;
190
191                         if (first)
192                                 o.WriteLine ();
193                         first = false;
194                         
195                         OutlineMemberAttribute (m);
196                         OutlineOperator (m);
197                         
198                         o.WriteLine ();
199                 }
200
201                 first = true;
202                 
203                 foreach (PropertyInfo pi in Comparer.Sort (t.GetProperties (DefaultFlags))) {
204                         
205                         if (! ((pi.CanRead  && ShowMember (pi.GetGetMethod (true))) ||
206                                (pi.CanWrite && ShowMember (pi.GetSetMethod (true)))))
207                                 continue;
208                         
209                         if (first)
210                                 o.WriteLine ();
211                         first = false;
212                         
213                         OutlineMemberAttribute (pi);
214                         OutlineProperty (pi);
215                         
216                         o.WriteLine ();
217                 }
218                 
219                 first = true;
220
221                 foreach (FieldInfo fi in t.GetFields (DefaultFlags)) {
222                         
223                         if (! ShowMember (fi))
224                                 continue;
225                         
226                         if (first)
227                                 o.WriteLine ();
228                         first = false;
229                         
230                         OutlineMemberAttribute (fi);
231                         OutlineField (fi);
232                         
233                         o.WriteLine ();
234                 }
235
236                 first = true;
237                 
238                 foreach (EventInfo ei in Comparer.Sort (t.GetEvents (DefaultFlags))) {
239                         
240                         if (! ShowMember (ei.GetAddMethod (true)))
241                                 continue;
242                         
243                         if (first)
244                                 o.WriteLine ();
245                         first = false;
246                         
247                         OutlineMemberAttribute (ei);
248                         OutlineEvent (ei);
249                         
250                         o.WriteLine ();
251                 }
252
253                 first = true;
254
255                 foreach (Type ntype in Comparer.Sort (t.GetNestedTypes (DefaultFlags))) {
256                         
257                         if (! ShowMember (ntype))
258                                 continue;
259                         
260                         if (first)
261                                 o.WriteLine ();
262                         first = false;
263                         
264                         new Outline (ntype, o, declared_only, show_private, filter_obsolete).OutlineType ();
265                 }
266                 
267                 o.Indent--; o.WriteLine ("}");
268         }
269         
270         BindingFlags DefaultFlags {
271                 get {
272                         BindingFlags f = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
273                         
274                         if (declared_only)
275                                 f |= BindingFlags.DeclaredOnly;
276                         
277                         return f;
278                 }
279         }
280
281         // FIXME: add other interesting attributes?
282         void OutlineAttributes ()
283         {
284                 if (t.IsSerializable)
285                         o.WriteLine ("[Serializable]");
286
287                 if (t.IsDefined (typeof (System.FlagsAttribute), true))
288                         o.WriteLine ("[Flags]");
289
290                 if (t.IsDefined (typeof (System.ObsoleteAttribute), true))
291                         o.WriteLine ("[Obsolete]");
292         }
293
294         void OutlineMemberAttribute (MemberInfo mi)
295         {
296                 if (!mi.IsDefined (typeof (System.ObsoleteAttribute), false))
297                         return;
298                 var oa = mi.GetCustomAttributes (typeof (System.ObsoleteAttribute), false) [0] as ObsoleteAttribute;
299                 var msg = oa.Message;
300                 o.WriteLine ("[Obsolete{0}]", msg == null || msg == "" ? "" : string.Format ("(\"{0}\")", msg));
301         }
302         
303         void OutlineEvent (EventInfo ei)
304         {
305                 MethodBase accessor = ei.GetAddMethod (true);
306                 
307                 o.Write (GetMethodVisibility (accessor));
308                 o.Write ("event ");
309                 o.Write (FormatType (ei.EventHandlerType));
310                 o.Write (" ");
311                 o.Write (ei.Name);
312                 o.Write (";");
313         }
314         
315         void OutlineConstructor (ConstructorInfo ci)
316         {
317                 o.Write (GetMethodVisibility (ci));
318                 o.Write (RemoveGenericArity (t.Name));
319                 o.Write (" (");
320                 OutlineParams (ci.GetParameters ());
321                 o.Write (");");
322         }
323         
324         
325         void OutlineProperty (PropertyInfo pi)
326         {
327                 ParameterInfo [] idxp = pi.GetIndexParameters ();
328                 MethodBase g = pi.GetGetMethod (true);
329                 MethodBase s = pi.GetSetMethod (true);
330                 MethodBase accessor = g != null ? g : s;
331                 
332                 if (pi.CanRead && pi.CanWrite) {
333
334                         
335                         // Get the more accessible accessor
336                         if ((g.Attributes & MethodAttributes.MemberAccessMask) !=
337                             (s.Attributes & MethodAttributes.MemberAccessMask)) {
338                                 
339                                 if (g.IsPublic) accessor = g;
340                                 else if (s.IsPublic) accessor = s;
341                                 else if (g.IsFamilyOrAssembly) accessor = g;
342                                 else if (s.IsFamilyOrAssembly) accessor = s;
343                                 else if (g.IsAssembly || g.IsFamily) accessor = g;
344                                 else if (s.IsAssembly || s.IsFamily) accessor = s;
345                         }
346                 }
347                 
348                 o.Write (GetMethodVisibility (accessor));
349                 o.Write (GetMethodModifiers  (accessor));
350                 o.Write (FormatType (pi.PropertyType));
351                 o.Write (" ");
352                 
353                 if (idxp.Length == 0)
354                         o.Write (pi.Name);
355                 else {
356                         o.Write ("this [");
357                         OutlineParams (idxp);
358                         o.Write ("]");
359                 }
360                 
361                 o.WriteLine (" {");
362                 o.Indent ++;
363                 
364                 if (g != null && ShowMember (g)) {
365                         if ((g.Attributes & MethodAttributes.MemberAccessMask) !=
366                             (accessor.Attributes & MethodAttributes.MemberAccessMask))
367                                 o.Write (GetMethodVisibility (g));
368                         o.WriteLine ("get;");
369                 }
370                 
371                 if (s != null && ShowMember (s)) {
372                         if ((s.Attributes & MethodAttributes.MemberAccessMask) !=
373                             (accessor.Attributes & MethodAttributes.MemberAccessMask))
374                                 o.Write (GetMethodVisibility (s));
375                         o.WriteLine ("set;");
376                 }
377                 
378                 o.Indent --;
379                 o.Write ("}");
380         }
381         
382         void OutlineMethod (MethodInfo mi)
383         {
384                 if (MethodIsExplicitIfaceImpl (mi)) {
385                         o.Write (FormatType (mi.ReturnType));
386                         o.Write (" ");
387                         // MSFT has no way to get the method that we are overriding
388                         // from the interface. this would allow us to pretty print
389                         // the type name (and be more correct if there compiler
390                         // were to do some strange naming thing).
391                 } else {
392                         o.Write (GetMethodVisibility (mi));
393                         o.Write (GetMethodModifiers  (mi));
394                         o.Write (FormatType (mi.ReturnType));
395                         o.Write (" ");
396                 }
397
398                 o.Write (mi.Name);
399                 o.Write (FormatGenericParams (mi.GetGenericArguments ()));
400                 o.Write (" (");
401                 OutlineParams (mi.GetParameters ());
402                 o.Write (")");
403                 WriteGenericConstraints (mi.GetGenericArguments ());
404                 o.Write (";");
405         }
406         
407         void OutlineOperator (MethodInfo mi)
408         {
409                 o.Write (GetMethodVisibility (mi));
410                 o.Write (GetMethodModifiers  (mi));
411                 if (mi.Name == "op_Explicit" || mi.Name == "op_Implicit") {
412                         o.Write (mi.Name.Substring (3).ToLower ());
413                         o.Write (" operator ");
414                         o.Write (FormatType (mi.ReturnType));
415                 } else {
416                         o.Write (FormatType (mi.ReturnType));
417                         o.Write (" operator ");
418                         o.Write (OperatorFromName (mi.Name));
419                 }
420                 o.Write (" (");
421                 OutlineParams (mi.GetParameters ());
422                 o.Write (");");
423         }
424         
425         void OutlineParams (ParameterInfo [] pi)
426         {
427                 int i = 0;
428                 foreach (ParameterInfo p in pi) {
429                         if (p.ParameterType.IsByRef) {
430                                 o.Write (p.IsOut ? "out " : "ref ");
431                                 o.Write (FormatType (p.ParameterType.GetElementType ()));
432                         } else if (p.IsDefined (typeof (ParamArrayAttribute), false)) {
433                                 o.Write ("params ");
434                                 o.Write (FormatType (p.ParameterType));
435                         } else {
436                                 o.Write (FormatType (p.ParameterType));
437                         }
438                         
439                         o.Write (" ");
440                         o.Write (p.Name);
441                         if (i + 1 < pi.Length)
442                                 o.Write (", ");
443                         i++;
444                 }
445         }
446
447         void OutlineField (FieldInfo fi)
448         {
449                 if (fi.IsPublic)   o.Write ("public ");
450                 if (fi.IsFamily)   o.Write ("protected ");
451                 if (fi.IsPrivate)  o.Write ("private ");
452                 if (fi.IsAssembly) o.Write ("internal ");
453                 if (fi.IsLiteral)  o.Write ("const ");
454                 else if (fi.IsStatic) o.Write ("static ");
455                 if (fi.IsInitOnly) o.Write ("readonly ");
456
457                 o.Write (FormatType (fi.FieldType));
458                 o.Write (" ");
459                 o.Write (fi.Name);
460                 if (fi.IsLiteral) { 
461                         object v = fi.GetValue (this);
462
463                         // TODO: Escape values here
464                         o.Write (" = ");
465                         if (v is char)
466                                 o.Write ("'{0}'", v);
467                         else if (v is string)
468                                 o.Write ("\"{0}\"", v);
469                         else
470                                 o.Write (fi.GetValue (this));
471                 }
472                 o.Write (";");
473         }
474
475         static string GetMethodVisibility (MethodBase m)
476         {
477                 // itnerfaces have no modifiers here
478                 if (m.DeclaringType.IsInterface)
479                         return "";
480                 
481                 if (m.IsPublic)   return "public ";
482                 if (m.IsFamily)   return "protected ";
483                 if (m.IsPrivate)  return "private ";
484                 if (m.IsAssembly) return "internal ";
485                         
486                 return null;
487         }
488         
489         static string GetMethodModifiers (MethodBase method)
490         {
491                 if (method.IsStatic)
492                         return "static ";
493
494                 if (method.IsFinal) {
495                         // This will happen if you have
496                         // class X : IA {
497                         //   public void A () {}
498                         //   static void Main () {}
499                         // }
500                         // interface IA {
501                         //   void A ();
502                         // }
503                         //
504                         // A needs to be virtual (the CLR requires
505                         // methods implementing an iface be virtual),
506                         // but can not be inherited. It also can not
507                         // be inherited. In C# this is represented
508                         // with no special modifiers
509
510                         if (method.IsVirtual)
511                                 return null;
512                         return "sealed ";
513                 }
514                 
515                 // all interface methods are "virtual" but we don't say that in c#
516                 if (method.IsVirtual && !method.DeclaringType.IsInterface) {
517                         if (method.IsAbstract)
518                                 return "abstract ";
519
520                         return ((method.Attributes & MethodAttributes.NewSlot) != 0) ?
521                                 "virtual " :
522                                 "override ";    
523                 }
524                                 
525                 return null;
526         }
527
528         static string GetTypeKind (Type t)
529         {
530                 if (t.IsEnum)
531                         return "enum";
532                 if (t.IsClass) {
533                         if (t.IsSubclassOf (typeof (System.MulticastDelegate)))
534                                 return "delegate";
535                         else
536                                 return "class";
537                 }
538                 if (t.IsInterface)
539                         return "interface";
540                 if (t.IsValueType)
541                         return "struct";
542                 return "class";
543         }
544         
545         static string GetTypeVisibility (Type t)
546         {
547                 switch (t.Attributes & TypeAttributes.VisibilityMask){
548                 case TypeAttributes.Public:
549                 case TypeAttributes.NestedPublic:
550                         return "public";
551
552                 case TypeAttributes.NestedFamily:
553                 case TypeAttributes.NestedFamANDAssem:
554                 case TypeAttributes.NestedFamORAssem:
555                         return "protected";
556
557                 default:
558                         return "internal";
559                 }
560         }
561
562         string FormatGenericParams (Type [] args)
563         {
564                 StringBuilder sb = new StringBuilder ();
565                 if (args.Length == 0)
566                         return "";
567                 
568                 sb.Append ("<");
569                 for (int i = 0; i < args.Length; i++) {
570                         if (i > 0)
571                                 sb.Append (",");
572                         sb.Append (FormatType (args [i]));
573                 }
574                 sb.Append (">");
575                 return sb.ToString ();
576         }
577
578         // TODO: fine tune this so that our output is less verbose. We need to figure
579         // out a way to do this while not making things confusing.
580         string FormatType (Type t)
581         {
582                 if (t == null)
583                         return "";
584
585                 string type = GetFullName (t);
586                 if (type == null)
587                         return t.ToString ();
588                 
589                 if (!type.StartsWith ("System.")) {
590                         if (t.Namespace == this.t.Namespace)
591                                 return t.Name;
592                         return type;
593                 }
594                 
595                 if (t.HasElementType) {
596                         Type et = t.GetElementType ();
597                         if (t.IsArray)
598                                 return FormatType (et) + " []";
599                         if (t.IsPointer)
600                                 return FormatType (et) + " *";
601                         if (t.IsByRef)
602                                 return "ref " + FormatType (et);
603                 }
604         
605                 switch (type) {
606                 case "System.Byte": return "byte";
607                 case "System.SByte": return "sbyte";
608                 case "System.Int16": return "short";
609                 case "System.Int32": return "int";
610                 case "System.Int64": return "long";
611                         
612                 case "System.UInt16": return "ushort";
613                 case "System.UInt32": return "uint";
614                 case "System.UInt64": return "ulong";
615                         
616                 case "System.Single":  return "float";
617                 case "System.Double":  return "double";
618                 case "System.Decimal": return "decimal";
619                 case "System.Boolean": return "bool";
620                 case "System.Char":    return "char";
621                 case "System.String":  return "string";
622                         
623                 case "System.Object":  return "object";
624                 case "System.Void":  return "void";
625                 }
626         
627                 if (type.LastIndexOf(".") == 6)
628                         return type.Substring(7);
629
630                 //
631                 // If the namespace of the type is the namespace of what
632                 // we are printing (or is a member of one if its children
633                 // don't print it. This basically means that in C# we would
634                 // automatically get the namespace imported by virtue of the
635                 // namespace {} block.
636                 //      
637                 if (this.t.Namespace.StartsWith (t.Namespace + ".") || t.Namespace == this.t.Namespace)
638                         return type.Substring (t.Namespace.Length + 1);
639         
640                 return type;
641         }
642
643         public static string RemoveGenericArity (string name)
644         {
645                 int start = 0;
646                 StringBuilder sb = new StringBuilder ();
647                 while (start < name.Length) {
648                         int pos = name.IndexOf ('`', start);
649                         if (pos < 0) {
650                                 sb.Append (name.Substring (start));
651                                 break;
652                         }
653                         sb.Append (name.Substring (start, pos-start));
654
655                         pos++;
656
657                         while ((pos < name.Length) && Char.IsNumber (name [pos]))
658                                 pos++;
659
660                         start = pos;
661                 }
662
663                 return sb.ToString ();
664         }
665
666         string GetTypeName (Type t)
667         {
668                 StringBuilder sb = new StringBuilder ();
669                 GetTypeName (sb, t);
670                 return sb.ToString ();
671         }
672
673         void GetTypeName (StringBuilder sb, Type t)
674         {
675                 sb.Append (RemoveGenericArity (t.Name));
676                 sb.Append (FormatGenericParams (t.GetGenericArguments ()));
677         }
678
679         string GetFullName (Type t)
680         {
681                 StringBuilder sb = new StringBuilder ();
682                 GetFullName_recursed (sb, t, false);
683                 return sb.ToString ();
684         }
685
686         void GetFullName_recursed (StringBuilder sb, Type t, bool recursed)
687         {
688                 if (t.IsGenericParameter) {
689                         sb.Append (t.Name);
690                         return;
691                 }
692
693                 if (t.DeclaringType != null) {
694                         GetFullName_recursed (sb, t.DeclaringType, true);
695                         sb.Append (".");
696                 }
697
698                 if (!recursed) {
699                         string ns = t.Namespace;
700                         if ((ns != null) && (ns != "")) {
701                                 sb.Append (ns);
702                                 sb.Append (".");
703                         }
704                 }
705
706                 GetTypeName (sb, t);
707         }
708
709         void WriteGenericConstraints (Type [] args)
710         {
711
712                 foreach (Type t in args) {
713                         bool first = true;
714                         Type[] ifaces = TypeGetInterfaces (t, true);
715                         
716                         GenericParameterAttributes attrs = t.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
717                         GenericParameterAttributes [] interesting = {
718                                 GenericParameterAttributes.ReferenceTypeConstraint,
719                                 GenericParameterAttributes.NotNullableValueTypeConstraint,
720                                 GenericParameterAttributes.DefaultConstructorConstraint
721                         };
722                         
723                         if (t.BaseType != typeof (object) || ifaces.Length != 0 || attrs != 0) {
724                                 o.Write (" where ");
725                                 o.Write (FormatType (t));
726                                 o.Write (" : ");
727                         }
728
729                         if (t.BaseType != typeof (object)) {
730                                 o.Write (FormatType (t.BaseType));
731                                 first = false;
732                         }
733
734                         foreach (Type iface in ifaces) {
735                                 if (!first)
736                                         o.Write (", ");
737                                 first = false;
738                                 
739                                 o.Write (FormatType (iface));
740                         }
741
742                         foreach (GenericParameterAttributes a in interesting) {
743                                 if ((attrs & a) == 0)
744                                         continue;
745                                 
746                                 if (!first)
747                                         o.Write (", ");
748                                 first = false;
749                                 
750                                 switch (a) {
751                                 case GenericParameterAttributes.ReferenceTypeConstraint:
752                                         o.Write ("class");
753                                         break;
754                                 case GenericParameterAttributes.NotNullableValueTypeConstraint:
755                                         o.Write ("struct");
756                                         break;
757                                 case GenericParameterAttributes.DefaultConstructorConstraint:
758                                         o.Write ("new ()");
759                                         break;
760                                 }
761                         }
762                 }
763         }
764  
765         string OperatorFromName (string name)
766         {
767                 switch (name) {
768                 case "op_UnaryPlus": return "+";
769                 case "op_UnaryNegation": return "-";
770                 case "op_LogicalNot": return "!";
771                 case "op_OnesComplement": return "~";
772                 case "op_Increment": return "++";
773                 case "op_Decrement": return "--";
774                 case "op_True": return "true";
775                 case "op_False": return "false";
776                 case "op_Addition": return "+";
777                 case "op_Subtraction": return "-";
778                 case "op_Multiply": return "*";
779                 case "op_Division": return "/";
780                 case "op_Modulus": return "%";
781                 case "op_BitwiseAnd": return "&";
782                 case "op_BitwiseOr": return "|";
783                 case "op_ExclusiveOr": return "^";
784                 case "op_LeftShift": return "<<";
785                 case "op_RightShift": return ">>";
786                 case "op_Equality": return "==";
787                 case "op_Inequality": return "!=";
788                 case "op_GreaterThan": return ">";
789                 case "op_LessThan": return "<";
790                 case "op_GreaterThanOrEqual": return ">=";
791                 case "op_LessThanOrEqual": return "<=";
792                 default: return name;
793                 }
794         }
795
796         bool MethodIsExplicitIfaceImpl (MethodBase mb)
797         {
798                 if (!(mb.IsFinal && mb.IsVirtual && mb.IsPrivate))
799                         return false;
800                 
801                 // UGH msft has no way to get the info about what method is
802                 // getting overriden. Another reason to use cecil :-)
803                 //
804                 //MethodInfo mi = mb as MethodInfo;
805                 //if (mi == null)
806                 //      return false;
807                 //
808                 //Console.WriteLine (mi.GetBaseDefinition ().DeclaringType);
809                 //return mi.GetBaseDefinition ().DeclaringType.IsInterface;
810                 
811                 // So, we guess that virtual final private methods only come
812                 // from ifaces :-)
813                 return true;
814         }
815         
816         bool ShowMember (MemberInfo mi)
817         {
818                 if (mi.MemberType == MemberTypes.Constructor && ((MethodBase) mi).IsStatic)
819                         return false;
820                 
821                 if (show_private)
822                         return true;
823
824                 if (filter_obsolete && mi.IsDefined (typeof (ObsoleteAttribute), false))
825                         return false;
826                 
827                 switch (mi.MemberType) {
828                 case MemberTypes.Constructor:
829                 case MemberTypes.Method:
830                         MethodBase mb = mi as MethodBase;
831                 
832                         if (mb.IsFamily || mb.IsPublic || mb.IsFamilyOrAssembly)
833                                 return true;
834                         
835                         if (MethodIsExplicitIfaceImpl (mb))
836                                 return true;
837                                         
838                         return false;
839                 
840                 
841                 case MemberTypes.Field:
842                         FieldInfo fi = mi as FieldInfo;
843                 
844                         if (fi.IsFamily || fi.IsPublic || fi.IsFamilyOrAssembly)
845                                 return true;
846                         
847                         return false;
848                 
849                 
850                 case MemberTypes.NestedType:
851                 case MemberTypes.TypeInfo:
852                         Type t = mi as Type;
853                 
854                         switch (t.Attributes & TypeAttributes.VisibilityMask){
855                         case TypeAttributes.Public:
856                         case TypeAttributes.NestedPublic:
857                         case TypeAttributes.NestedFamily:
858                         case TypeAttributes.NestedFamORAssem:
859                                 return true;
860                         }
861                         
862                         return false;
863                 }
864                 
865                 // What am I !!!
866                 return true;
867         }
868
869         static Type [] TypeGetInterfaces (Type t, bool declonly)
870         {
871                 if (t.IsGenericParameter)
872                         return new Type [0];
873
874                 Type [] ifaces = t.GetInterfaces ();
875                 if (! declonly)
876                         return ifaces;
877
878                 // Handle Object. Also, optimize for no interfaces
879                 if (t.BaseType == null || ifaces.Length == 0)
880                         return ifaces;
881
882                 ArrayList ar = new ArrayList ();
883
884                 foreach (Type i in ifaces)
885                         if (! i.IsAssignableFrom (t.BaseType))
886                                 ar.Add (i);
887
888                 return (Type []) ar.ToArray (typeof (Type));
889         }
890 }
891
892 public class Comparer : IComparer  {
893         delegate int ComparerFunc (object a, object b);
894         
895         ComparerFunc cmp;
896         
897         Comparer (ComparerFunc f)
898         {
899                 this.cmp = f;
900         }
901         
902         public int Compare (object a, object b)
903         {
904                 return cmp (a, b);
905         }
906
907         static int CompareType (object a, object b)
908         {
909                 Type type1 = (Type) a;
910                 Type type2 = (Type) b;
911
912                 if (type1.IsSubclassOf (typeof (System.MulticastDelegate)) != type2.IsSubclassOf (typeof (System.MulticastDelegate)))
913                                 return (type1.IsSubclassOf (typeof (System.MulticastDelegate)))? -1:1;
914                 return string.Compare (type1.Name, type2.Name);
915                         
916         }
917
918 //      static Comparer TypeComparer = new Comparer (new ComparerFunc (CompareType));
919
920 //      static Type [] Sort (Type [] types)
921 //      {
922 //              Array.Sort (types, TypeComparer);
923 //              return types;
924 //      }
925         
926         static int CompareMemberInfo (object a, object b)
927         {
928                 return string.Compare (((MemberInfo) a).Name, ((MemberInfo) b).Name);
929         }
930         
931         static Comparer MemberInfoComparer = new Comparer (new ComparerFunc (CompareMemberInfo));
932         
933         public static MemberInfo [] Sort (MemberInfo [] inf)
934         {
935                 Array.Sort (inf, MemberInfoComparer);
936                 return inf;
937         }
938         
939         static int CompareMethodBase (object a, object b)
940         {
941                 MethodBase aa = (MethodBase) a, bb = (MethodBase) b;
942                 
943                 if (aa.IsStatic == bb.IsStatic) {
944                         int c = CompareMemberInfo (a, b);
945                         if (c != 0)
946                                 return c;
947                         ParameterInfo [] ap, bp;
948
949                         //
950                         // Sort overloads by the names of their types
951                         // put methods with fewer params first.
952                         //
953                         
954                         ap = aa.GetParameters ();
955                         bp = bb.GetParameters ();
956                         int n = System.Math.Min (ap.Length, bp.Length);
957
958                         for (int i = 0; i < n; i ++)
959                                 if ((c = CompareType (ap [i].ParameterType, bp [i].ParameterType)) != 0)
960                                         return c;
961
962                         return ap.Length.CompareTo (bp.Length);
963                 }
964                 if (aa.IsStatic)
965                         return -1;
966                 
967                 return 1;
968         }
969         
970         static Comparer MethodBaseComparer = new Comparer (new ComparerFunc (CompareMethodBase));
971         
972         public static MethodBase [] Sort (MethodBase [] inf)
973         {
974                 Array.Sort (inf, MethodBaseComparer);
975                 return inf;
976         }
977         
978         static int ComparePropertyInfo (object a, object b)
979         {
980                 PropertyInfo aa = (PropertyInfo) a, bb = (PropertyInfo) b;
981                 
982                 bool astatic = (aa.CanRead ? aa.GetGetMethod (true) : aa.GetSetMethod (true)).IsStatic;
983                 bool bstatic = (bb.CanRead ? bb.GetGetMethod (true) : bb.GetSetMethod (true)).IsStatic;
984                 
985                 if (astatic == bstatic)
986                         return CompareMemberInfo (a, b);
987                 
988                 if (astatic)
989                         return -1;
990                 
991                 return 1;
992         }
993         
994         static Comparer PropertyInfoComparer = new Comparer (new ComparerFunc (ComparePropertyInfo));
995         
996         public static PropertyInfo [] Sort (PropertyInfo [] inf)
997         {
998                 Array.Sort (inf, PropertyInfoComparer);
999                 return inf;
1000         }
1001         
1002         static int CompareEventInfo (object a, object b)
1003         {
1004                 EventInfo aa = (EventInfo) a, bb = (EventInfo) b;
1005                 
1006                 bool astatic = aa.GetAddMethod (true).IsStatic;
1007                 bool bstatic = bb.GetAddMethod (true).IsStatic;
1008                 
1009                 if (astatic == bstatic)
1010                         return CompareMemberInfo (a, b);
1011                 
1012                 if (astatic)
1013                         return -1;
1014                 
1015                 return 1;
1016         }
1017         
1018         static Comparer EventInfoComparer = new Comparer (new ComparerFunc (CompareEventInfo));
1019         
1020         public static EventInfo [] Sort (EventInfo [] inf)
1021         {
1022                 Array.Sort (inf, EventInfoComparer);
1023                 return inf;
1024         }
1025 }
1026 }
1027
1028 #endif