2 // outline -- support for rendering in monop
3 // Some code stolen from updater.cs in monodoc.
6 // Ben Maurer (bmaurer@users.sourceforge.net)
12 using System.Reflection;
13 using System.Collections;
14 using System.CodeDom.Compiler;
17 public class Outline {
22 public Outline (Type t, TextWriter output)
25 this.o = new IndentedTextWriter (output, " ");
28 public void OutlineType (BindingFlags flags)
33 o.Write (GetTypeVisibility (t));
35 if (t.IsClass && !t.IsSubclassOf (typeof (System.MulticastDelegate))) {
37 o.Write (t.IsAbstract ? " static" : " sealed");
38 else if (t.IsAbstract)
39 o.Write (" abstract");
43 o.Write (GetTypeKind (t));
46 Type [] interfaces = (Type []) Comparer.Sort (t.GetInterfaces ());
47 Type parent = t.BaseType;
49 if (t.IsSubclassOf (typeof (System.MulticastDelegate))) {
52 method = t.GetMethod ("Invoke");
54 o.Write (FormatType (method.ReturnType));
58 OutlineParams (method.GetParameters ());
65 if (((parent != null && parent != typeof (object) && parent != typeof (ValueType)) || interfaces.Length != 0) && ! t.IsEnum) {
69 if (parent != null && parent != typeof (object) && parent != typeof (ValueType)) {
70 o.Write (FormatType (parent));
74 foreach (Type intf in interfaces) {
75 if (!first) o.Write (", ");
78 o.Write (FormatType (intf));
87 foreach (FieldInfo fi in t.GetFields (BindingFlags.Public | BindingFlags.Static)) {
95 o.Indent--; o.WriteLine ("}");
101 foreach (ConstructorInfo ci in t.GetConstructors (flags)) {
106 OutlineConstructor (ci);
114 foreach (MethodInfo m in Comparer.Sort (t.GetMethods (flags))) {
115 if ((m.Attributes & MethodAttributes.SpecialName) != 0)
129 foreach (PropertyInfo pi in Comparer.Sort (t.GetProperties (flags))) {
135 OutlineProperty (pi);
142 foreach (FieldInfo fi in t.GetFields (flags)) {
155 foreach (EventInfo ei in Comparer.Sort (t.GetEvents (flags))) {
168 foreach (Type ntype in Comparer.Sort (t.GetNestedTypes (flags))) {
174 new Outline (ntype, o).OutlineType (flags);
177 o.Indent--; o.WriteLine ("}");
180 // FIXME: add other interesting attributes?
181 void OutlineAttributes ()
183 if (t.IsSerializable)
184 o.WriteLine ("[Serializable]");
186 if (t.IsDefined (typeof (System.FlagsAttribute), true))
187 o.WriteLine ("[Flags]");
189 if (t.IsDefined (typeof (System.ObsoleteAttribute), true))
190 o.WriteLine ("[Obsolete]");
193 void OutlineEvent (EventInfo ei)
195 MethodBase accessor = ei.GetAddMethod ();
197 o.Write (GetMethodVisibility (accessor));
199 o.Write (FormatType (ei.EventHandlerType));
205 void OutlineConstructor (ConstructorInfo ci)
207 o.Write (GetMethodVisibility (ci));
210 OutlineParams (ci.GetParameters ());
215 void OutlineProperty (PropertyInfo pi)
217 ParameterInfo [] idxp = pi.GetIndexParameters ();
218 MethodBase accessor = pi.CanRead ? pi.GetGetMethod (true) : pi.GetSetMethod (true);
220 o.Write (GetMethodVisibility (accessor));
221 o.Write (GetMethodModifiers (accessor));
222 o.Write (FormatType (pi.PropertyType));
225 if (idxp.Length == 0)
229 OutlineParams (idxp);
236 if (pi.CanRead) o.WriteLine ("get;");
237 if (pi.CanWrite) o.WriteLine ("set;");
243 void OutlineMethod (MethodInfo mi)
245 o.Write (GetMethodVisibility (mi));
246 o.Write (GetMethodModifiers (mi));
247 o.Write (FormatType (mi.ReturnType));
251 OutlineParams (mi.GetParameters ());
255 void OutlineParams (ParameterInfo [] pi)
258 foreach (ParameterInfo p in pi) {
259 if (p.ParameterType.IsByRef) {
260 o.Write (p.IsOut ? "out " : "ref ");
261 o.Write (FormatType (p.ParameterType.GetElementType ()));
262 } else if (p.IsDefined (typeof (ParamArrayAttribute), false)) {
264 o.Write (FormatType (p.ParameterType));
266 o.Write (FormatType (p.ParameterType));
271 if (i + 1 < pi.Length)
277 void OutlineField (FieldInfo fi)
279 if (fi.IsPublic) o.Write ("public ");
280 if (fi.IsFamily) o.Write ("protected ");
281 if (fi.IsPrivate) o.Write ("private ");
282 if (fi.IsAssembly) o.Write ("internal ");
283 if (fi.IsLiteral) o.Write ("const ");
284 o.Write (FormatType (fi.FieldType));
290 o.Write (fi.GetValue (this));
295 static string GetMethodVisibility (MethodBase m)
297 if (m.IsPublic) return "public ";
298 if (m.IsFamily) return "protected ";
299 if (m.IsPrivate) return "private ";
300 if (m.IsAssembly) return "internal ";
305 static string GetMethodModifiers (MethodBase method)
310 if (method.IsVirtual)
311 return ((method.Attributes & MethodAttributes.NewSlot) != 0) ?
318 static string GetTypeKind (Type t)
323 if (t.IsSubclassOf (typeof (System.MulticastDelegate)))
335 static string GetTypeVisibility (Type t)
337 switch (t.Attributes & TypeAttributes.VisibilityMask){
338 case TypeAttributes.Public:
339 case TypeAttributes.NestedPublic:
342 case TypeAttributes.NestedFamily:
343 case TypeAttributes.NestedFamANDAssem:
344 case TypeAttributes.NestedFamORAssem:
352 static string FormatType (Type t)
354 string type = t.FullName;
355 if (!type.StartsWith ("System."))
358 if (t.HasElementType) {
359 Type et = t.GetElementType ();
361 return FormatType (et) + " []";
363 return FormatType (et) + " *";
365 return "ref " + FormatType (et);
369 case "System.Byte": return "byte";
370 case "System.SByte": return "sbyte";
371 case "System.Int16": return "short";
372 case "System.Int32": return "int";
373 case "System.Int64": return "long";
375 case "System.UInt16": return "ushort";
376 case "System.UInt32": return "uint";
377 case "System.UInt64": return "ulong";
379 case "System.Single": return "float";
380 case "System.Double": return "double";
381 case "System.Decimal": return "decimal";
382 case "System.Boolean": return "bool";
383 case "System.Char": return "char";
384 case "System.String": return "string";
386 case "System.Object": return "object";
387 case "System.Void": return "void";
390 if (type.LastIndexOf(".") == 6)
391 return type.Substring(7);
397 public class Comparer : IComparer {
398 delegate int ComparerFunc (object a, object b);
402 Comparer (ComparerFunc f)
407 public int Compare (object a, object b)
412 static int CompareType (object a, object b)
414 Type type1 = (Type) a;
415 Type type2 = (Type) b;
417 if (type1.IsSubclassOf (typeof (System.MulticastDelegate)) != type2.IsSubclassOf (typeof (System.MulticastDelegate)))
418 return (type1.IsSubclassOf (typeof (System.MulticastDelegate)))? -1:1;
419 return string.Compare (type1.Name, type2.Name);
423 static Comparer TypeComparer = new Comparer (new ComparerFunc (CompareType));
425 static Type [] Sort (Type [] types)
427 Array.Sort (types, TypeComparer);
431 static int CompareMemberInfo (object a, object b)
433 return string.Compare (((MemberInfo) a).Name, ((MemberInfo) b).Name);
436 static Comparer MemberInfoComparer = new Comparer (new ComparerFunc (CompareMemberInfo));
438 public static MemberInfo [] Sort (MemberInfo [] inf)
440 Array.Sort (inf, MemberInfoComparer);
444 static int CompareMethodBase (object a, object b)
446 MethodBase aa = (MethodBase) a, bb = (MethodBase) b;
448 if (aa.IsStatic == bb.IsStatic)
449 return CompareMemberInfo (a, b);
457 static Comparer MethodBaseComparer = new Comparer (new ComparerFunc (CompareMethodBase));
459 public static MethodBase [] Sort (MethodBase [] inf)
461 Array.Sort (inf, MethodBaseComparer);
465 static int ComparePropertyInfo (object a, object b)
467 PropertyInfo aa = (PropertyInfo) a, bb = (PropertyInfo) b;
469 bool astatic = (aa.CanRead ? aa.GetGetMethod (true) : aa.GetSetMethod (true)).IsStatic;
470 bool bstatic = (bb.CanRead ? bb.GetGetMethod (true) : bb.GetSetMethod (true)).IsStatic;
472 if (astatic == bstatic)
473 return CompareMemberInfo (a, b);
481 static Comparer PropertyInfoComparer = new Comparer (new ComparerFunc (ComparePropertyInfo));
483 public static PropertyInfo [] Sort (PropertyInfo [] inf)
485 Array.Sort (inf, PropertyInfoComparer);
489 static int CompareEventInfo (object a, object b)
491 EventInfo aa = (EventInfo) a, bb = (EventInfo) b;
493 bool astatic = aa.GetAddMethod (true).IsStatic;
494 bool bstatic = bb.GetAddMethod (true).IsStatic;
496 if (astatic == bstatic)
497 return CompareMemberInfo (a, b);
505 static Comparer EventInfoComparer = new Comparer (new ComparerFunc (CompareEventInfo));
507 public static EventInfo [] Sort (EventInfo [] inf)
509 Array.Sort (inf, EventInfoComparer);