[mono/tests] Fix out of tree build.
[mono-project.git] / mcs / tools / monop / outline.cs
blob5a97797c95b078efdd8f437f8fabf438eaebc568
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 //
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.
32 using System;
33 using System.Collections;
34 using System.CodeDom.Compiler;
35 using System.IO;
36 using System.Text;
37 #if STATIC
38 using IKVM.Reflection;
39 using Type=IKVM.Reflection.Type;
40 #else
41 using System.Reflection;
42 #endif
44 namespace Mono.CSharp {
46 public static class TypeExtensions {
47 public static string GetNamespace (this Type t)
49 // IKVM crashes here with a null ref sometimes
50 try {
51 return t.Namespace;
52 } catch {
53 return null;
58 public class Outline {
59 bool declared_only;
60 bool show_private;
61 bool filter_obsolete;
63 IndentedTextWriter o;
64 Type t;
65 Type type_multicast_delegate, type_object, type_value_type, type_int, type_flags_attribute, type_obsolete_attribute, type_param_array_attribute;
67 #if STATIC
68 Universe universe;
69 Assembly mscorlib;
71 public Outline (System.Type t, TextWriter output, bool declared_only, bool show_private, bool filter_obsolete)
73 throw new NotImplementedException ();
76 public Outline (Universe universe, Assembly mscorlib, Type t, TextWriter output, bool declared_only, bool show_private, bool filter_obsolete)
78 if (universe == null)
79 throw new ArgumentNullException ("universe");
80 if (mscorlib == null)
81 throw new ArgumentNullException ("mscorlib");
82 this.universe = universe;
83 this.mscorlib = mscorlib;
84 this.t = t;
85 this.o = new IndentedTextWriter (output, "\t");
86 this.declared_only = declared_only;
87 this.show_private = show_private;
88 this.filter_obsolete = filter_obsolete;
90 type_multicast_delegate = mscorlib.GetType("System.MulticastDelegate");
91 type_object = mscorlib.GetType ("System.Object");
92 type_value_type = mscorlib.GetType ("System.ValueType");
93 type_int = mscorlib.GetType ("System.Int32");
94 type_flags_attribute = mscorlib.GetType ("System.FlagsAttribute");
95 type_obsolete_attribute = mscorlib.GetType ("System.ObsoleteAttribute");
96 type_param_array_attribute = mscorlib.GetType ("System.ParamArrayAttribute");
98 #else
99 public Outline (Type t, TextWriter output, bool declared_only, bool show_private, bool filter_obsolete)
101 this.t = t;
102 this.o = new IndentedTextWriter (output, "\t");
103 this.declared_only = declared_only;
104 this.show_private = show_private;
105 this.filter_obsolete = filter_obsolete;
107 type_multicast_delegate = typeof (System.MulticastDelegate);
108 type_object = typeof (object);
109 type_value_type = typeof (ValueType);
110 type_int = typeof (int);
111 type_flags_attribute = typeof (FlagsAttribute);
112 type_obsolete_attribute = typeof (ObsoleteAttribute);
113 type_param_array_attribute = typeof (ParamArrayAttribute);
115 #endif
117 public void OutlineType ()
119 bool first;
121 OutlineAttributes ();
122 o.Write (GetTypeVisibility (t));
124 if (t.IsClass && !t.IsSubclassOf (type_multicast_delegate)) {
125 if (t.IsSealed)
126 o.Write (t.IsAbstract ? " static" : " sealed");
127 else if (t.IsAbstract)
128 o.Write (" abstract");
131 o.Write (" ");
132 o.Write (GetTypeKind (t));
133 o.Write (" ");
135 Type [] interfaces = (Type []) Comparer.Sort (TypeGetInterfaces (t, declared_only));
136 Type parent = t.BaseType;
138 if (t.IsSubclassOf (type_multicast_delegate)) {
139 MethodInfo method;
141 method = t.GetMethod ("Invoke");
143 o.Write (FormatType (method.ReturnType));
144 o.Write (" ");
145 o.Write (GetTypeName (t));
146 o.Write (" (");
147 OutlineParams (method.GetParameters ());
148 o.Write (")");
150 WriteGenericConstraints (t.GetGenericArguments ());
152 o.WriteLine (";");
153 return;
156 o.Write (GetTypeName (t));
157 if (((parent != null && parent != type_object && parent != type_value_type) || interfaces.Length != 0) && ! t.IsEnum) {
158 first = true;
159 o.Write (" : ");
161 if (parent != null && parent != type_object && parent != type_value_type) {
162 o.Write (FormatType (parent));
163 first = false;
166 foreach (Type intf in interfaces) {
167 if (!first) o.Write (", ");
168 first = false;
170 o.Write (FormatType (intf));
174 if (t.IsEnum) {
175 Type underlyingType = t.GetEnumUnderlyingType ();
176 if (underlyingType != type_int)
177 o.Write (" : {0}", FormatType (underlyingType));
179 WriteGenericConstraints (t.GetGenericArguments ());
180 o.WriteLine (" {");
181 o.Indent++;
183 if (t.IsEnum) {
184 bool is_first = true;
185 foreach (FieldInfo fi in t.GetFields (BindingFlags.Public | BindingFlags.Static)) {
187 if (! is_first)
188 o.WriteLine (",");
189 is_first = false;
190 o.Write (fi.Name);
192 o.WriteLine ();
193 o.Indent--; o.WriteLine ("}");
194 return;
197 first = true;
199 foreach (ConstructorInfo ci in t.GetConstructors (DefaultFlags)) {
200 if (! ShowMember (ci))
201 continue;
203 if (first)
204 o.WriteLine ();
205 first = false;
207 OutlineMemberAttribute (ci);
208 OutlineConstructor (ci);
210 o.WriteLine ();
214 first = true;
216 foreach (MethodInfo m in Comparer.Sort (t.GetMethods (DefaultFlags))) {
218 if (! ShowMember (m))
219 continue;
221 if ((m.Attributes & MethodAttributes.SpecialName) != 0)
222 continue;
224 if (first)
225 o.WriteLine ();
226 first = false;
228 OutlineMemberAttribute (m);
229 OutlineMethod (m);
231 o.WriteLine ();
234 first = true;
236 foreach (MethodInfo m in t.GetMethods (DefaultFlags)) {
238 if (! ShowMember (m))
239 continue;
241 if ((m.Attributes & MethodAttributes.SpecialName) == 0)
242 continue;
243 if (!(m.Name.StartsWith ("op_")))
244 continue;
246 if (first)
247 o.WriteLine ();
248 first = false;
250 OutlineMemberAttribute (m);
251 OutlineOperator (m);
253 o.WriteLine ();
256 first = true;
258 foreach (PropertyInfo pi in Comparer.Sort (t.GetProperties (DefaultFlags))) {
260 if (! ((pi.CanRead && ShowMember (pi.GetGetMethod (true))) ||
261 (pi.CanWrite && ShowMember (pi.GetSetMethod (true)))))
262 continue;
264 if (first)
265 o.WriteLine ();
266 first = false;
268 OutlineMemberAttribute (pi);
269 OutlineProperty (pi);
271 o.WriteLine ();
274 first = true;
276 foreach (FieldInfo fi in t.GetFields (DefaultFlags)) {
278 if (! ShowMember (fi))
279 continue;
281 if (first)
282 o.WriteLine ();
283 first = false;
285 OutlineMemberAttribute (fi);
286 OutlineField (fi);
288 o.WriteLine ();
291 first = true;
293 foreach (EventInfo ei in Comparer.Sort (t.GetEvents (DefaultFlags))) {
295 if (! ShowMember (ei.GetAddMethod (true)))
296 continue;
298 if (first)
299 o.WriteLine ();
300 first = false;
302 OutlineMemberAttribute (ei);
303 OutlineEvent (ei);
305 o.WriteLine ();
308 first = true;
310 foreach (Type ntype in Comparer.Sort (t.GetNestedTypes (DefaultFlags))) {
312 if (! ShowMember (ntype))
313 continue;
315 if (first)
316 o.WriteLine ();
317 first = false;
319 #if STATIC
320 new Outline (universe, mscorlib, ntype, o, declared_only, show_private, filter_obsolete).OutlineType ();
321 #else
322 new Outline (ntype, o, declared_only, show_private, filter_obsolete).OutlineType ();
323 #endif
326 o.Indent--; o.WriteLine ("}");
329 BindingFlags DefaultFlags {
330 get {
331 BindingFlags f = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
333 if (declared_only)
334 f |= BindingFlags.DeclaredOnly;
336 return f;
340 // FIXME: add other interesting attributes?
341 void OutlineAttributes ()
343 if (t.IsSerializable)
344 o.WriteLine ("[Serializable]");
346 if (t.IsDefined (type_flags_attribute, true))
347 o.WriteLine ("[Flags]");
349 if (t.IsDefined (type_obsolete_attribute, true))
350 o.WriteLine ("[Obsolete]");
353 void OutlineMemberAttribute (MemberInfo mi)
355 var attrs = mi.GetCustomAttributesData ();
356 if (attrs.Count > 0)
357 o.WriteLine ("");
359 foreach (var attr in attrs)
360 o.WriteLine (attr);
363 void OutlineEvent (EventInfo ei)
365 MethodBase accessor = ei.GetAddMethod (true);
367 o.Write (GetMethodVisibility (accessor));
368 o.Write ("event ");
369 o.Write (FormatType (ei.EventHandlerType));
370 o.Write (" ");
371 o.Write (ei.Name);
372 o.Write (";");
375 void OutlineConstructor (ConstructorInfo ci)
377 o.Write (GetMethodVisibility (ci));
378 o.Write (RemoveGenericArity (t.Name));
379 o.Write (" (");
380 OutlineParams (ci.GetParameters ());
381 o.Write (");");
385 void OutlineProperty (PropertyInfo pi)
387 ParameterInfo [] idxp = pi.GetIndexParameters ();
388 MethodBase g = pi.GetGetMethod (true);
389 MethodBase s = pi.GetSetMethod (true);
390 MethodBase accessor = g != null ? g : s;
392 if (pi.CanRead && pi.CanWrite) {
395 // Get the more accessible accessor
396 if ((g.Attributes & MethodAttributes.MemberAccessMask) !=
397 (s.Attributes & MethodAttributes.MemberAccessMask)) {
399 if (g.IsPublic) accessor = g;
400 else if (s.IsPublic) accessor = s;
401 else if (g.IsFamilyOrAssembly) accessor = g;
402 else if (s.IsFamilyOrAssembly) accessor = s;
403 else if (g.IsAssembly || g.IsFamily) accessor = g;
404 else if (s.IsAssembly || s.IsFamily) accessor = s;
408 o.Write (GetMethodVisibility (accessor));
409 o.Write (GetMethodModifiers (accessor));
410 o.Write (FormatType (pi.PropertyType));
411 o.Write (" ");
413 if (idxp.Length == 0)
414 o.Write (pi.Name);
415 else {
416 o.Write ("this [");
417 OutlineParams (idxp);
418 o.Write ("]");
421 o.WriteLine (" {");
422 o.Indent ++;
424 if (g != null && ShowMember (g)) {
425 if ((g.Attributes & MethodAttributes.MemberAccessMask) !=
426 (accessor.Attributes & MethodAttributes.MemberAccessMask))
427 o.Write (GetMethodVisibility (g));
428 o.WriteLine ("get;");
431 if (s != null && ShowMember (s)) {
432 if ((s.Attributes & MethodAttributes.MemberAccessMask) !=
433 (accessor.Attributes & MethodAttributes.MemberAccessMask))
434 o.Write (GetMethodVisibility (s));
435 o.WriteLine ("set;");
438 o.Indent --;
439 o.Write ("}");
442 void OutlineMethod (MethodInfo mi)
444 if (MethodIsExplicitIfaceImpl (mi)) {
445 o.Write (FormatType (mi.ReturnType));
446 o.Write (" ");
447 // MSFT has no way to get the method that we are overriding
448 // from the interface. this would allow us to pretty print
449 // the type name (and be more correct if there compiler
450 // were to do some strange naming thing).
451 } else {
452 o.Write (GetMethodVisibility (mi));
453 o.Write (GetMethodModifiers (mi));
454 o.Write (FormatType (mi.ReturnType));
455 o.Write (" ");
458 o.Write (mi.Name);
459 o.Write (FormatGenericParams (mi.GetGenericArguments ()));
460 o.Write (" (");
461 OutlineParams (mi.GetParameters ());
462 o.Write (")");
463 WriteGenericConstraints (mi.GetGenericArguments ());
464 o.Write (";");
467 void OutlineOperator (MethodInfo mi)
469 o.Write (GetMethodVisibility (mi));
470 o.Write (GetMethodModifiers (mi));
471 if (mi.Name == "op_Explicit" || mi.Name == "op_Implicit") {
472 o.Write (mi.Name.Substring (3).ToLower ());
473 o.Write (" operator ");
474 o.Write (FormatType (mi.ReturnType));
475 } else {
476 o.Write (FormatType (mi.ReturnType));
477 o.Write (" operator ");
478 o.Write (OperatorFromName (mi.Name));
480 o.Write (" (");
481 OutlineParams (mi.GetParameters ());
482 o.Write (");");
485 void OutlineParams (ParameterInfo [] pi)
487 int i = 0;
488 foreach (ParameterInfo p in pi) {
489 if (p.ParameterType.IsByRef) {
490 o.Write (p.IsOut ? "out " : "ref ");
491 o.Write (FormatType (p.ParameterType.GetElementType ()));
492 } else if (p.IsDefined (type_param_array_attribute, false)) {
493 o.Write ("params ");
494 o.Write (FormatType (p.ParameterType));
495 } else {
496 o.Write (FormatType (p.ParameterType));
499 o.Write (" ");
500 o.Write (p.Name);
501 if (i + 1 < pi.Length)
502 o.Write (", ");
503 i++;
507 void OutlineField (FieldInfo fi)
509 if (fi.IsPublic) o.Write ("public ");
510 if (fi.IsFamily) o.Write ("protected ");
511 if (fi.IsPrivate) o.Write ("private ");
512 if (fi.IsAssembly) o.Write ("internal ");
513 if (fi.IsLiteral) o.Write ("const ");
514 else if (fi.IsStatic) o.Write ("static ");
515 if (fi.IsInitOnly) o.Write ("readonly ");
517 o.Write (FormatType (fi.FieldType));
518 o.Write (" ");
519 o.Write (fi.Name);
520 if (fi.IsLiteral) {
521 object v = fi.GetRawConstantValue ();
523 // TODO: Escape values here
524 o.Write (" = ");
525 if (v is char)
526 o.Write ("'{0}'", v);
527 else if (v is string)
528 o.Write ("\"{0}\"", v);
529 else
530 o.Write (fi.GetRawConstantValue ());
532 o.Write (";");
535 static string GetMethodVisibility (MethodBase m)
537 // itnerfaces have no modifiers here
538 if (m.DeclaringType.IsInterface)
539 return "";
541 if (m.IsPublic) return "public ";
542 if (m.IsFamily) return "protected ";
543 if (m.IsPrivate) return "private ";
544 if (m.IsAssembly) return "internal ";
546 return null;
549 static string GetMethodModifiers (MethodBase method)
551 if (method.IsStatic)
552 return "static ";
554 if (method.IsFinal) {
555 // This will happen if you have
556 // class X : IA {
557 // public void A () {}
558 // static void Main () {}
559 // }
560 // interface IA {
561 // void A ();
562 // }
564 // A needs to be virtual (the CLR requires
565 // methods implementing an iface be virtual),
566 // but can not be inherited. It also can not
567 // be inherited. In C# this is represented
568 // with no special modifiers
570 if (method.IsVirtual)
571 return null;
572 return "sealed ";
575 // all interface methods are "virtual" but we don't say that in c#
576 if (method.IsVirtual && !method.DeclaringType.IsInterface) {
577 if (method.IsAbstract)
578 return "abstract ";
580 return ((method.Attributes & MethodAttributes.NewSlot) != 0) ?
581 "virtual " :
582 "override ";
585 return null;
588 string GetTypeKind (Type t)
590 if (t.IsEnum)
591 return "enum";
592 if (t.IsClass) {
593 if (t.IsSubclassOf (type_multicast_delegate))
594 return "delegate";
595 else
596 return "class";
598 if (t.IsInterface)
599 return "interface";
600 if (t.IsValueType)
601 return "struct";
602 return "class";
605 static string GetTypeVisibility (Type t)
607 switch (t.Attributes & TypeAttributes.VisibilityMask){
608 case TypeAttributes.Public:
609 case TypeAttributes.NestedPublic:
610 return "public";
612 case TypeAttributes.NestedFamily:
613 case TypeAttributes.NestedFamANDAssem:
614 case TypeAttributes.NestedFamORAssem:
615 return "protected";
617 default:
618 return "internal";
622 string FormatGenericParams (Type [] args)
624 StringBuilder sb = new StringBuilder ();
625 if (args.Length == 0)
626 return "";
628 sb.Append ("<");
629 for (int i = 0; i < args.Length; i++) {
630 if (i > 0)
631 sb.Append (",");
632 sb.Append (FormatType (args [i]));
634 sb.Append (">");
635 return sb.ToString ();
638 // TODO: fine tune this so that our output is less verbose. We need to figure
639 // out a way to do this while not making things confusing.
640 string FormatType (Type t)
642 if (t == null)
643 return "";
645 string type = GetFullName (t);
646 if (type == null)
647 return t.ToString ();
649 if (!type.StartsWith ("System.")) {
650 if (type.IndexOf (".") == -1)
651 return type;
652 if (t.GetNamespace () == this.t.GetNamespace ())
653 return t.Name;
654 return type;
657 if (t.HasElementType) {
658 Type et = t.GetElementType ();
659 if (t.IsArray)
660 return FormatType (et) + " []";
661 if (t.IsPointer)
662 return FormatType (et) + " *";
663 if (t.IsByRef)
664 return "ref " + FormatType (et);
667 switch (type) {
668 case "System.Byte": return "byte";
669 case "System.SByte": return "sbyte";
670 case "System.Int16": return "short";
671 case "System.Int32": return "int";
672 case "System.Int64": return "long";
674 case "System.UInt16": return "ushort";
675 case "System.UInt32": return "uint";
676 case "System.UInt64": return "ulong";
678 case "System.Single": return "float";
679 case "System.Double": return "double";
680 case "System.Decimal": return "decimal";
681 case "System.Boolean": return "bool";
682 case "System.Char": return "char";
683 case "System.String": return "string";
685 case "System.Object": return "object";
686 case "System.Void": return "void";
689 if (type.LastIndexOf(".") == 6)
690 return type.Substring(7);
693 // If the namespace of the type is the namespace of what
694 // we are printing (or is a member of one if its children
695 // don't print it. This basically means that in C# we would
696 // automatically get the namespace imported by virtue of the
697 // namespace {} block.
699 if (this.t.Namespace != null && (this.t.Namespace.StartsWith (t.Namespace + ".") || t.Namespace == this.t.Namespace))
700 return type.Substring (t.Namespace.Length + 1);
702 return type;
705 public static string RemoveGenericArity (string name)
707 int start = 0;
708 StringBuilder sb = new StringBuilder ();
709 while (start < name.Length) {
710 int pos = name.IndexOf ('`', start);
711 if (pos < 0) {
712 sb.Append (name.Substring (start));
713 break;
715 sb.Append (name.Substring (start, pos-start));
717 pos++;
719 while ((pos < name.Length) && Char.IsNumber (name [pos]))
720 pos++;
722 start = pos;
725 return sb.ToString ();
728 string GetTypeName (Type t)
730 StringBuilder sb = new StringBuilder ();
731 GetTypeName (sb, t);
732 return sb.ToString ();
735 void GetTypeName (StringBuilder sb, Type t)
737 sb.Append (RemoveGenericArity (t.Name));
738 sb.Append (FormatGenericParams (t.GetGenericArguments ()));
741 string GetFullName (Type t)
743 StringBuilder sb = new StringBuilder ();
744 GetFullName_recursed (sb, t, false);
745 return sb.ToString ();
748 void GetFullName_recursed (StringBuilder sb, Type t, bool recursed)
750 if (t.IsGenericParameter) {
751 sb.Append (t.Name);
752 return;
755 if (t.DeclaringType != null) {
756 GetFullName_recursed (sb, t.DeclaringType, true);
757 sb.Append (".");
760 if (!recursed) {
761 string ns;
762 ns = t.GetNamespace ();
763 if ((ns != null) && (ns != "")) {
764 sb.Append (ns);
765 sb.Append (".");
769 GetTypeName (sb, t);
772 void WriteGenericConstraints (Type [] args)
775 foreach (Type t in args) {
776 bool first = true;
777 Type[] ifaces = TypeGetInterfaces (t, true);
779 GenericParameterAttributes attrs = t.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
780 GenericParameterAttributes [] interesting = {
781 GenericParameterAttributes.ReferenceTypeConstraint,
782 GenericParameterAttributes.NotNullableValueTypeConstraint,
783 GenericParameterAttributes.DefaultConstructorConstraint
786 if (t.BaseType != type_object || ifaces.Length != 0 || attrs != 0) {
787 o.Write (" where ");
788 o.Write (FormatType (t));
789 o.Write (" : ");
792 if (t.BaseType != type_object) {
793 o.Write (FormatType (t.BaseType));
794 first = false;
797 foreach (Type iface in ifaces) {
798 if (!first)
799 o.Write (", ");
800 first = false;
802 o.Write (FormatType (iface));
805 foreach (GenericParameterAttributes a in interesting) {
806 if ((attrs & a) == 0)
807 continue;
809 if (!first)
810 o.Write (", ");
811 first = false;
813 switch (a) {
814 case GenericParameterAttributes.ReferenceTypeConstraint:
815 o.Write ("class");
816 break;
817 case GenericParameterAttributes.NotNullableValueTypeConstraint:
818 o.Write ("struct");
819 break;
820 case GenericParameterAttributes.DefaultConstructorConstraint:
821 o.Write ("new ()");
822 break;
828 string OperatorFromName (string name)
830 switch (name) {
831 case "op_UnaryPlus": return "+";
832 case "op_UnaryNegation": return "-";
833 case "op_LogicalNot": return "!";
834 case "op_OnesComplement": return "~";
835 case "op_Increment": return "++";
836 case "op_Decrement": return "--";
837 case "op_True": return "true";
838 case "op_False": return "false";
839 case "op_Addition": return "+";
840 case "op_Subtraction": return "-";
841 case "op_Multiply": return "*";
842 case "op_Division": return "/";
843 case "op_Modulus": return "%";
844 case "op_BitwiseAnd": return "&";
845 case "op_BitwiseOr": return "|";
846 case "op_ExclusiveOr": return "^";
847 case "op_LeftShift": return "<<";
848 case "op_RightShift": return ">>";
849 case "op_Equality": return "==";
850 case "op_Inequality": return "!=";
851 case "op_GreaterThan": return ">";
852 case "op_LessThan": return "<";
853 case "op_GreaterThanOrEqual": return ">=";
854 case "op_LessThanOrEqual": return "<=";
855 default: return name;
859 bool MethodIsExplicitIfaceImpl (MethodBase mb)
861 if (!(mb.IsFinal && mb.IsVirtual && mb.IsPrivate))
862 return false;
864 // UGH msft has no way to get the info about what method is
865 // getting overriden. Another reason to use cecil :-)
867 //MethodInfo mi = mb as MethodInfo;
868 //if (mi == null)
869 // return false;
871 //Console.WriteLine (mi.GetBaseDefinition ().DeclaringType);
872 //return mi.GetBaseDefinition ().DeclaringType.IsInterface;
874 // So, we guess that virtual final private methods only come
875 // from ifaces :-)
876 return true;
879 bool ShowMember (MemberInfo mi)
881 if (mi.MemberType == MemberTypes.Constructor && ((MethodBase) mi).IsStatic)
882 return false;
884 if (show_private)
885 return true;
887 if (filter_obsolete && mi.IsDefined (type_obsolete_attribute, false))
888 return false;
890 switch (mi.MemberType) {
891 case MemberTypes.Constructor:
892 case MemberTypes.Method:
893 MethodBase mb = mi as MethodBase;
895 if (mb.IsFamily || mb.IsPublic || mb.IsFamilyOrAssembly)
896 return true;
898 if (MethodIsExplicitIfaceImpl (mb))
899 return true;
901 return false;
904 case MemberTypes.Field:
905 FieldInfo fi = mi as FieldInfo;
907 if (fi.IsFamily || fi.IsPublic || fi.IsFamilyOrAssembly)
908 return true;
910 return false;
913 case MemberTypes.NestedType:
914 case MemberTypes.TypeInfo:
915 Type t = mi as Type;
917 switch (t.Attributes & TypeAttributes.VisibilityMask){
918 case TypeAttributes.Public:
919 case TypeAttributes.NestedPublic:
920 case TypeAttributes.NestedFamily:
921 case TypeAttributes.NestedFamORAssem:
922 return true;
925 return false;
928 // What am I !!!
929 return true;
932 static Type [] TypeGetInterfaces (Type t, bool declonly)
934 if (t.IsGenericParameter)
935 return new Type [0];
937 Type [] ifaces = t.GetInterfaces ();
938 if (! declonly)
939 return ifaces;
941 // Handle Object. Also, optimize for no interfaces
942 if (t.BaseType == null || ifaces.Length == 0)
943 return ifaces;
945 ArrayList ar = new ArrayList ();
947 foreach (Type i in ifaces)
948 if (! i.IsAssignableFrom (t.BaseType))
949 ar.Add (i);
951 return (Type []) ar.ToArray (typeof (Type));
955 public class Comparer : IComparer {
956 delegate int ComparerFunc (object a, object b);
958 ComparerFunc cmp;
960 Comparer (ComparerFunc f)
962 this.cmp = f;
965 public int Compare (object a, object b)
967 return cmp (a, b);
970 static int CompareType (object a, object b)
972 Type type1 = (Type) a;
973 Type type2 = (Type) b;
975 return string.Compare (type1.Name, type2.Name);
979 // static Comparer TypeComparer = new Comparer (new ComparerFunc (CompareType));
981 // static Type [] Sort (Type [] types)
982 // {
983 // Array.Sort (types, TypeComparer);
984 // return types;
985 // }
987 static int CompareMemberInfo (object a, object b)
989 return string.Compare (((MemberInfo) a).Name, ((MemberInfo) b).Name);
992 static Comparer MemberInfoComparer = new Comparer (new ComparerFunc (CompareMemberInfo));
994 public static MemberInfo [] Sort (MemberInfo [] inf)
996 Array.Sort (inf, MemberInfoComparer);
997 return inf;
1000 static int CompareMethodBase (object a, object b)
1002 MethodBase aa = (MethodBase) a, bb = (MethodBase) b;
1004 if (aa.IsStatic == bb.IsStatic) {
1005 int c = CompareMemberInfo (a, b);
1006 if (c != 0)
1007 return c;
1008 ParameterInfo [] ap, bp;
1011 // Sort overloads by the names of their types
1012 // put methods with fewer params first.
1015 ap = aa.GetParameters ();
1016 bp = bb.GetParameters ();
1017 int n = System.Math.Min (ap.Length, bp.Length);
1019 for (int i = 0; i < n; i ++)
1020 if ((c = CompareType (ap [i].ParameterType, bp [i].ParameterType)) != 0)
1021 return c;
1023 return ap.Length.CompareTo (bp.Length);
1025 if (aa.IsStatic)
1026 return -1;
1028 return 1;
1031 static Comparer MethodBaseComparer = new Comparer (new ComparerFunc (CompareMethodBase));
1033 public static MethodBase [] Sort (MethodBase [] inf)
1035 Array.Sort (inf, MethodBaseComparer);
1036 return inf;
1039 static int ComparePropertyInfo (object a, object b)
1041 PropertyInfo aa = (PropertyInfo) a, bb = (PropertyInfo) b;
1043 bool astatic = (aa.CanRead ? aa.GetGetMethod (true) : aa.GetSetMethod (true)).IsStatic;
1044 bool bstatic = (bb.CanRead ? bb.GetGetMethod (true) : bb.GetSetMethod (true)).IsStatic;
1046 if (astatic == bstatic)
1047 return CompareMemberInfo (a, b);
1049 if (astatic)
1050 return -1;
1052 return 1;
1055 static Comparer PropertyInfoComparer = new Comparer (new ComparerFunc (ComparePropertyInfo));
1057 public static PropertyInfo [] Sort (PropertyInfo [] inf)
1059 Array.Sort (inf, PropertyInfoComparer);
1060 return inf;
1063 static int CompareEventInfo (object a, object b)
1065 EventInfo aa = (EventInfo) a, bb = (EventInfo) b;
1067 bool astatic = aa.GetAddMethod (true).IsStatic;
1068 bool bstatic = bb.GetAddMethod (true).IsStatic;
1070 if (astatic == bstatic)
1071 return CompareMemberInfo (a, b);
1073 if (astatic)
1074 return -1;
1076 return 1;
1079 static Comparer EventInfoComparer = new Comparer (new ComparerFunc (CompareEventInfo));
1081 public static EventInfo [] Sort (EventInfo [] inf)
1083 Array.Sort (inf, EventInfoComparer);
1084 return inf;