**** Merged from MCS ****
[mono-project.git] / mcs / tools / monop / outline.cs
blob3b30b3e228be179daab551e69ef2efa6092066ff
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 //
11 using System;
12 using System.Reflection;
13 using System.Collections;
14 using System.CodeDom.Compiler;
15 using System.IO;
17 public class Outline {
19 IndentedTextWriter o;
20 Type t;
22 public Outline (Type t, TextWriter output)
24 this.t = t;
25 this.o = new IndentedTextWriter (output, " ");
28 public void OutlineType (BindingFlags flags)
30 bool first;
32 OutlineAttributes ();
33 o.Write (GetTypeVisibility (t));
35 if (t.IsClass && !t.IsSubclassOf (typeof (System.MulticastDelegate))) {
36 if (t.IsSealed)
37 o.Write (t.IsAbstract ? " static" : " sealed");
38 else if (t.IsAbstract)
39 o.Write (" abstract");
42 o.Write (" ");
43 o.Write (GetTypeKind (t));
44 o.Write (" ");
46 Type [] interfaces = (Type []) Comparer.Sort (t.GetInterfaces ());
47 Type parent = t.BaseType;
49 if (t.IsSubclassOf (typeof (System.MulticastDelegate))) {
50 MethodInfo method;
52 method = t.GetMethod ("Invoke");
54 o.Write (FormatType (method.ReturnType));
55 o.Write (" ");
56 o.Write (t.Name);
57 o.Write (" (");
58 OutlineParams (method.GetParameters ());
59 o.WriteLine (");");
61 return;
64 o.Write (t.Name);
65 if (((parent != null && parent != typeof (object) && parent != typeof (ValueType)) || interfaces.Length != 0) && ! t.IsEnum) {
66 first = true;
67 o.Write (" : ");
69 if (parent != null && parent != typeof (object) && parent != typeof (ValueType)) {
70 o.Write (FormatType (parent));
71 first = false;
74 foreach (Type intf in interfaces) {
75 if (!first) o.Write (", ");
76 first = false;
78 o.Write (FormatType (intf));
82 o.WriteLine (" {");
83 o.Indent++;
85 if (t.IsEnum) {
86 bool is_first = true;
87 foreach (FieldInfo fi in t.GetFields (BindingFlags.Public | BindingFlags.Static)) {
89 if (! is_first)
90 o.WriteLine (",");
91 is_first = false;
92 o.Write (fi.Name);
94 o.WriteLine ();
95 o.Indent--; o.WriteLine ("}");
96 return;
99 first = true;
101 foreach (ConstructorInfo ci in t.GetConstructors (flags)) {
102 if (first)
103 o.WriteLine ();
104 first = false;
106 OutlineConstructor (ci);
108 o.WriteLine ();
112 first = true;
114 foreach (MethodInfo m in Comparer.Sort (t.GetMethods (flags))) {
115 if ((m.Attributes & MethodAttributes.SpecialName) != 0)
116 continue;
118 if (first)
119 o.WriteLine ();
120 first = false;
122 OutlineMethod (m);
124 o.WriteLine ();
127 first = true;
129 foreach (PropertyInfo pi in Comparer.Sort (t.GetProperties (flags))) {
131 if (first)
132 o.WriteLine ();
133 first = false;
135 OutlineProperty (pi);
137 o.WriteLine ();
140 first = true;
142 foreach (FieldInfo fi in t.GetFields (flags)) {
144 if (first)
145 o.WriteLine ();
146 first = false;
148 OutlineField (fi);
150 o.WriteLine ();
153 first = true;
155 foreach (EventInfo ei in Comparer.Sort (t.GetEvents (flags))) {
157 if (first)
158 o.WriteLine ();
159 first = false;
161 OutlineEvent (ei);
163 o.WriteLine ();
166 first = true;
168 foreach (Type ntype in Comparer.Sort (t.GetNestedTypes (flags))) {
170 if (first)
171 o.WriteLine ();
172 first = false;
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));
198 o.Write ("event ");
199 o.Write (FormatType (ei.EventHandlerType));
200 o.Write (" ");
201 o.Write (ei.Name);
202 o.Write (";");
205 void OutlineConstructor (ConstructorInfo ci)
207 o.Write (GetMethodVisibility (ci));
208 o.Write (t.Name);
209 o.Write (" (");
210 OutlineParams (ci.GetParameters ());
211 o.Write (");");
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));
223 o.Write (" ");
225 if (idxp.Length == 0)
226 o.Write (pi.Name);
227 else {
228 o.Write ("this [");
229 OutlineParams (idxp);
230 o.Write ("]");
233 o.WriteLine (" {");
234 o.Indent ++;
236 if (pi.CanRead) o.WriteLine ("get;");
237 if (pi.CanWrite) o.WriteLine ("set;");
239 o.Indent --;
240 o.Write ("}");
243 void OutlineMethod (MethodInfo mi)
245 o.Write (GetMethodVisibility (mi));
246 o.Write (GetMethodModifiers (mi));
247 o.Write (FormatType (mi.ReturnType));
248 o.Write (" ");
249 o.Write (mi.Name);
250 o.Write (" (");
251 OutlineParams (mi.GetParameters ());
252 o.Write (");");
255 void OutlineParams (ParameterInfo [] pi)
257 int i = 0;
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)) {
263 o.Write ("params ");
264 o.Write (FormatType (p.ParameterType));
265 } else {
266 o.Write (FormatType (p.ParameterType));
269 o.Write (" ");
270 o.Write (p.Name);
271 if (i + 1 < pi.Length)
272 o.Write (", ");
273 i++;
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));
285 o.Write (" ");
286 o.Write (fi.Name);
287 if (fi.IsLiteral)
289 o.Write (" = ");
290 o.Write (fi.GetValue (this));
292 o.Write (";");
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 ";
302 return null;
305 static string GetMethodModifiers (MethodBase method)
307 if (method.IsStatic)
308 return "static ";
310 if (method.IsVirtual)
311 return ((method.Attributes & MethodAttributes.NewSlot) != 0) ?
312 "virtual " :
313 "override ";
315 return null;
318 static string GetTypeKind (Type t)
320 if (t.IsEnum)
321 return "enum";
322 if (t.IsClass) {
323 if (t.IsSubclassOf (typeof (System.MulticastDelegate)))
324 return "delegate";
325 else
326 return "class";
328 if (t.IsInterface)
329 return "interface";
330 if (t.IsValueType)
331 return "struct";
332 return "class";
335 static string GetTypeVisibility (Type t)
337 switch (t.Attributes & TypeAttributes.VisibilityMask){
338 case TypeAttributes.Public:
339 case TypeAttributes.NestedPublic:
340 return "public";
342 case TypeAttributes.NestedFamily:
343 case TypeAttributes.NestedFamANDAssem:
344 case TypeAttributes.NestedFamORAssem:
345 return "protected";
347 default:
348 return "internal";
352 string FormatType (Type t)
354 string type = t.FullName;
356 if (t.Namespace == this.t.Namespace)
357 return t.Name;
359 if (!type.StartsWith ("System."))
360 return type;
362 if (t.HasElementType) {
363 Type et = t.GetElementType ();
364 if (t.IsArray)
365 return FormatType (et) + " []";
366 if (t.IsPointer)
367 return FormatType (et) + " *";
368 if (t.IsByRef)
369 return "ref " + FormatType (et);
372 switch (type) {
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);
397 return type;
401 public class Comparer : IComparer {
402 delegate int ComparerFunc (object a, object b);
404 ComparerFunc cmp;
406 Comparer (ComparerFunc f)
408 this.cmp = f;
411 public int Compare (object a, object b)
413 return cmp (a, 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);
432 return types;
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);
445 return inf;
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);
455 if (aa.IsStatic)
456 return -1;
458 return 1;
461 static Comparer MethodBaseComparer = new Comparer (new ComparerFunc (CompareMethodBase));
463 public static MethodBase [] Sort (MethodBase [] inf)
465 Array.Sort (inf, MethodBaseComparer);
466 return inf;
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);
479 if (astatic)
480 return -1;
482 return 1;
485 static Comparer PropertyInfoComparer = new Comparer (new ComparerFunc (ComparePropertyInfo));
487 public static PropertyInfo [] Sort (PropertyInfo [] inf)
489 Array.Sort (inf, PropertyInfoComparer);
490 return inf;
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);
503 if (astatic)
504 return -1;
506 return 1;
509 static Comparer EventInfoComparer = new Comparer (new ComparerFunc (CompareEventInfo));
511 public static EventInfo [] Sort (EventInfo [] inf)
513 Array.Sort (inf, EventInfoComparer);
514 return inf;