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)
31 o.Write (GetTypeVisibility (t));
33 o.Write (GetTypeKind (t));
36 Type [] interfaces = (Type []) Comparer.Sort (t.GetInterfaces ());
37 Type parent = t.BaseType;
39 if (t.IsSubclassOf (typeof (System.MulticastDelegate))) {
42 method = t.GetMethod ("Invoke");
44 o.Write (FormatType (method.ReturnType));
48 OutlineParams (method.GetParameters ());
55 if (((parent != null && parent != typeof (object) && parent != typeof (ValueType)) || interfaces.Length != 0) && ! t.IsEnum) {
59 if (parent != null && parent != typeof (object) && parent != typeof (ValueType)) {
60 o.Write (FormatType (parent));
64 foreach (Type intf in interfaces) {
65 if (!first) o.Write (", ");
68 o.Write (FormatType (intf));
77 foreach (FieldInfo fi in t.GetFields (BindingFlags.Public | BindingFlags.Static)) {
85 o.Indent--; o.WriteLine ("}");
89 foreach (ConstructorInfo ci in t.GetConstructors (flags)) {
90 OutlineConstructor (ci);
97 foreach (MethodInfo m in Comparer.Sort (t.GetMethods (flags))) {
98 if ((m.Attributes & MethodAttributes.SpecialName) != 0)
108 foreach (PropertyInfo pi in Comparer.Sort (t.GetProperties (flags))) {
109 OutlineProperty (pi);
116 foreach (FieldInfo fi in t.GetFields (flags))
123 foreach (EventInfo ei in Comparer.Sort (t.GetEvents (flags))) {
131 foreach (Type ntype in Comparer.Sort (t.GetNestedTypes (flags)))
132 new Outline (ntype, o).OutlineType (flags);
134 o.Indent--; o.WriteLine ("}");
137 // FIXME: add other interesting attributes?
138 void OutlineAttributes ()
140 if (t.IsSerializable)
141 o.WriteLine ("[Serializable]");
143 if (t.GetCustomAttributes (typeof (System.FlagsAttribute), true).Length > 0)
144 o.WriteLine ("[Flags]");
147 void OutlineEvent (EventInfo ei)
149 MethodBase accessor = ei.GetAddMethod ();
151 o.Write (GetMethodVisibility (accessor));
153 o.Write (FormatType (ei.EventHandlerType));
159 void OutlineConstructor (ConstructorInfo ci)
161 o.Write (GetMethodVisibility (ci));
164 OutlineParams (ci.GetParameters ());
169 void OutlineProperty (PropertyInfo pi)
171 ParameterInfo [] idxp = pi.GetIndexParameters ();
172 MethodBase accessor = pi.CanRead ? pi.GetGetMethod (true) : pi.GetSetMethod (true);
174 o.Write (GetMethodVisibility (accessor));
175 o.Write (GetMethodModifiers (accessor));
176 o.Write (FormatType (pi.PropertyType));
179 if (idxp.Length == 0)
183 OutlineParams (idxp);
190 if (pi.CanRead) o.WriteLine ("get;");
191 if (pi.CanWrite) o.WriteLine ("set;");
197 void OutlineMethod (MethodInfo mi)
199 o.Write (GetMethodVisibility (mi));
200 o.Write (GetMethodModifiers (mi));
201 o.Write (FormatType (mi.ReturnType));
205 OutlineParams (mi.GetParameters ());
209 void OutlineParams (ParameterInfo [] pi)
212 foreach (ParameterInfo p in pi) {
213 if (p.ParameterType.IsByRef) {
214 o.Write (p.IsOut ? "out " : "ref ");
215 o.Write (FormatType (p.ParameterType.GetElementType ()));
216 } else if (p.GetCustomAttributes (typeof (ParamArrayAttribute), false).Length > 0) {
218 o.Write (FormatType (p.ParameterType));
220 o.Write (FormatType (p.ParameterType));
225 if (i + 1 < pi.Length)
231 void OutlineField (FieldInfo fi)
233 if (fi.IsPublic) o.Write ("public ");
234 if (fi.IsFamily) o.Write ("protected ");
235 if (fi.IsPrivate) o.Write ("private ");
236 if (fi.IsAssembly) o.Write ("internal ");
237 if (fi.IsLiteral) o.Write ("const ");
238 o.Write (FormatType (fi.FieldType));
244 o.Write (fi.GetValue (this));
249 static string GetMethodVisibility (MethodBase m)
251 if (m.IsPublic) return "public ";
252 if (m.IsFamily) return "protected ";
253 if (m.IsPrivate) return "private ";
254 if (m.IsAssembly) return "internal ";
259 static string GetMethodModifiers (MethodBase method)
264 if (method.IsVirtual)
265 return ((method.Attributes & MethodAttributes.NewSlot) != 0) ?
272 static string GetTypeKind (Type t)
277 if (t.IsSubclassOf (typeof (System.MulticastDelegate)))
289 static string GetTypeVisibility (Type t)
291 switch (t.Attributes & TypeAttributes.VisibilityMask){
292 case TypeAttributes.Public:
293 case TypeAttributes.NestedPublic:
296 case TypeAttributes.NestedFamily:
297 case TypeAttributes.NestedFamANDAssem:
298 case TypeAttributes.NestedFamORAssem:
306 static string FormatType (Type t)
308 string type = t.FullName;
309 if (!type.StartsWith ("System."))
312 if (t.HasElementType) {
313 Type et = t.GetElementType ();
315 return FormatType (et) + " []";
317 return FormatType (et) + " *";
319 return "ref " + FormatType (et);
323 case "System.Byte": return "byte";
324 case "System.SByte": return "sbyte";
325 case "System.Int16": return "short";
326 case "System.Int32": return "int";
327 case "System.Int64": return "long";
329 case "System.UInt16": return "ushort";
330 case "System.UInt32": return "uint";
331 case "System.UInt64": return "ulong";
333 case "System.Single": return "float";
334 case "System.Double": return "double";
335 case "System.Decimal": return "decimal";
336 case "System.Boolean": return "bool";
337 case "System.Char": return "char";
338 case "System.String": return "string";
340 case "System.Object": return "object";
341 case "System.Void": return "void";
344 if (type.LastIndexOf(".") == 6)
345 return type.Substring(7);
351 public class Comparer : IComparer {
352 delegate int ComparerFunc (object a, object b);
356 Comparer (ComparerFunc f)
361 public int Compare (object a, object b)
366 static int CompareType (object a, object b)
368 Type type1 = (Type) a;
369 Type type2 = (Type) b;
371 if (type1.IsSubclassOf (typeof (System.MulticastDelegate)) != type2.IsSubclassOf (typeof (System.MulticastDelegate)))
372 return (type1.IsSubclassOf (typeof (System.MulticastDelegate)))? -1:1;
373 return string.Compare (type1.Name, type2.Name);
377 static Comparer TypeComparer = new Comparer (new ComparerFunc (CompareType));
379 static Type [] Sort (Type [] types)
381 Array.Sort (types, TypeComparer);
385 static int CompareMemberInfo (object a, object b)
387 return string.Compare (((MemberInfo) a).Name, ((MemberInfo) b).Name);
390 static Comparer MemberInfoComparer = new Comparer (new ComparerFunc (CompareMemberInfo));
392 public static MemberInfo [] Sort (MemberInfo [] inf)
394 Array.Sort (inf, MemberInfoComparer);
398 static int CompareMethodBase (object a, object b)
400 MethodBase aa = (MethodBase) a, bb = (MethodBase) b;
402 if (aa.IsStatic == bb.IsStatic)
403 return CompareMemberInfo (a, b);
411 static Comparer MethodBaseComparer = new Comparer (new ComparerFunc (CompareMethodBase));
413 public static MethodBase [] Sort (MethodBase [] inf)
415 Array.Sort (inf, MethodBaseComparer);
419 static int ComparePropertyInfo (object a, object b)
421 PropertyInfo aa = (PropertyInfo) a, bb = (PropertyInfo) b;
423 bool astatic = (aa.CanRead ? aa.GetGetMethod (true) : aa.GetSetMethod (true)).IsStatic;
424 bool bstatic = (bb.CanRead ? bb.GetGetMethod (true) : bb.GetSetMethod (true)).IsStatic;
426 if (astatic == bstatic)
427 return CompareMemberInfo (a, b);
435 static Comparer PropertyInfoComparer = new Comparer (new ComparerFunc (ComparePropertyInfo));
437 public static PropertyInfo [] Sort (PropertyInfo [] inf)
439 Array.Sort (inf, PropertyInfoComparer);
443 static int CompareEventInfo (object a, object b)
445 EventInfo aa = (EventInfo) a, bb = (EventInfo) b;
447 bool astatic = aa.GetAddMethod (true).IsStatic;
448 bool bstatic = bb.GetAddMethod (true).IsStatic;
450 if (astatic == bstatic)
451 return CompareMemberInfo (a, b);
459 static Comparer EventInfoComparer = new Comparer (new ComparerFunc (CompareEventInfo));
461 public static EventInfo [] Sort (EventInfo [] inf)
463 Array.Sort (inf, EventInfoComparer);