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 string FormatType (Type t
)
354 string type
= t
.FullName
;
356 if (t
.Namespace
== this.t
.Namespace
)
359 if (!type
.StartsWith ("System."))
362 if (t
.HasElementType
) {
363 Type et
= t
.GetElementType ();
365 return FormatType (et
) + " []";
367 return FormatType (et
) + " *";
369 return "ref " + FormatType (et
);
373 case "System.Byte": return "byte";
374 case "System.SByte": return "sbyte";
375 case "System.Int16": return "short";
376 case "System.Int32": return "int";
377 case "System.Int64": return "long";
379 case "System.UInt16": return "ushort";
380 case "System.UInt32": return "uint";
381 case "System.UInt64": return "ulong";
383 case "System.Single": return "float";
384 case "System.Double": return "double";
385 case "System.Decimal": return "decimal";
386 case "System.Boolean": return "bool";
387 case "System.Char": return "char";
388 case "System.String": return "string";
390 case "System.Object": return "object";
391 case "System.Void": return "void";
394 if (type
.LastIndexOf(".") == 6)
395 return type
.Substring(7);
401 public class Comparer
: IComparer
{
402 delegate int ComparerFunc (object a
, object b
);
406 Comparer (ComparerFunc f
)
411 public int Compare (object a
, object b
)
416 static int CompareType (object a
, object b
)
418 Type type1
= (Type
) a
;
419 Type type2
= (Type
) b
;
421 if (type1
.IsSubclassOf (typeof (System
.MulticastDelegate
)) != type2
.IsSubclassOf (typeof (System
.MulticastDelegate
)))
422 return (type1
.IsSubclassOf (typeof (System
.MulticastDelegate
)))? -1:1;
423 return string.Compare (type1
.Name
, type2
.Name
);
427 static Comparer TypeComparer
= new Comparer (new ComparerFunc (CompareType
));
429 static Type
[] Sort (Type
[] types
)
431 Array
.Sort (types
, TypeComparer
);
435 static int CompareMemberInfo (object a
, object b
)
437 return string.Compare (((MemberInfo
) a
).Name
, ((MemberInfo
) b
).Name
);
440 static Comparer MemberInfoComparer
= new Comparer (new ComparerFunc (CompareMemberInfo
));
442 public static MemberInfo
[] Sort (MemberInfo
[] inf
)
444 Array
.Sort (inf
, MemberInfoComparer
);
448 static int CompareMethodBase (object a
, object b
)
450 MethodBase aa
= (MethodBase
) a
, bb
= (MethodBase
) b
;
452 if (aa
.IsStatic
== bb
.IsStatic
)
453 return CompareMemberInfo (a
, b
);
461 static Comparer MethodBaseComparer
= new Comparer (new ComparerFunc (CompareMethodBase
));
463 public static MethodBase
[] Sort (MethodBase
[] inf
)
465 Array
.Sort (inf
, MethodBaseComparer
);
469 static int ComparePropertyInfo (object a
, object b
)
471 PropertyInfo aa
= (PropertyInfo
) a
, bb
= (PropertyInfo
) b
;
473 bool astatic
= (aa
.CanRead
? aa
.GetGetMethod (true) : aa
.GetSetMethod (true)).IsStatic
;
474 bool bstatic
= (bb
.CanRead
? bb
.GetGetMethod (true) : bb
.GetSetMethod (true)).IsStatic
;
476 if (astatic
== bstatic
)
477 return CompareMemberInfo (a
, b
);
485 static Comparer PropertyInfoComparer
= new Comparer (new ComparerFunc (ComparePropertyInfo
));
487 public static PropertyInfo
[] Sort (PropertyInfo
[] inf
)
489 Array
.Sort (inf
, PropertyInfoComparer
);
493 static int CompareEventInfo (object a
, object b
)
495 EventInfo aa
= (EventInfo
) a
, bb
= (EventInfo
) b
;
497 bool astatic
= aa
.GetAddMethod (true).IsStatic
;
498 bool bstatic
= bb
.GetAddMethod (true).IsStatic
;
500 if (astatic
== bstatic
)
501 return CompareMemberInfo (a
, b
);
509 static Comparer EventInfoComparer
= new Comparer (new ComparerFunc (CompareEventInfo
));
511 public static EventInfo
[] Sort (EventInfo
[] inf
)
513 Array
.Sort (inf
, EventInfoComparer
);