This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / tools / monop / outline.cs
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 //
10
11 using System;
12 using System.Reflection;
13 using System.Collections;
14 using System.CodeDom.Compiler;
15 using System.IO;
16         
17 public class Outline {
18         
19         IndentedTextWriter o;
20         Type t;
21         
22         public Outline (Type t, TextWriter output)
23         {
24                 this.t = t;
25                 this.o = new IndentedTextWriter (output, "    ");
26         }
27
28         public void OutlineType (BindingFlags flags)
29         {
30                 o.Write (GetTypeVisibility (t));
31                 o.Write (" ");
32                 o.Write (GetTypeKind (t));
33                 o.Write (" ");
34                 
35                 Type [] interfaces = (Type []) Comparer.Sort (t.GetInterfaces ());
36                 Type parent = t.BaseType;
37
38                 if (t.IsSubclassOf (typeof (System.MulticastDelegate))) {
39                         MethodInfo method;
40
41                         method = t.GetMethod ("Invoke");
42
43                         o.Write (FormatType (method.ReturnType));
44                         o.Write (" ");
45                         o.Write (t.Name);
46                         o.Write (" (");
47                         OutlineParams (method.GetParameters ());
48                         o.WriteLine (");");
49
50                         return;
51                 }
52                 
53                 o.Write (t.Name);
54                 if (((parent != null && parent != typeof (object) && parent != typeof (ValueType)) || interfaces.Length != 0) && ! t.IsEnum) {
55                         bool first = true;
56                         o.Write (" : ");
57                         
58                         if (parent != null && parent != typeof (object) && parent != typeof (ValueType)) {
59                                 o.Write (FormatType (parent));
60                                 first = false;
61                         }
62                         
63                         foreach (Type intf in interfaces) {
64                                 if (!first) o.Write (", ");
65                                 first = false;
66                                 
67                                 o.Write (FormatType (intf));
68                         }
69                 }
70                 
71                 o.WriteLine (" {");
72                 o.Indent++;
73
74                 if (t.IsEnum) {
75                         bool is_first = true;
76                         foreach (FieldInfo fi in t.GetFields (BindingFlags.Public | BindingFlags.Static)) {
77                                 
78                                 if (! is_first)
79                                         o.WriteLine (",");
80                                 is_first = false;
81                                 o.Write (fi.Name);
82                         }
83                         o.WriteLine ();
84                         o.Indent--; o.WriteLine ("}");
85                         return;
86                 }
87                 
88                 foreach (ConstructorInfo ci in t.GetConstructors (flags)) {
89                         OutlineConstructor (ci);
90                         
91                         o.WriteLine ();
92                 }
93                 
94                 o.WriteLine ();
95                 
96                 foreach (MethodInfo m in Comparer.Sort (t.GetMethods (flags))) {
97                         if ((m.Attributes & MethodAttributes.SpecialName) != 0)
98                                 continue;
99                         
100                         OutlineMethod (m);
101                         
102                         o.WriteLine ();
103                 }
104                 
105                 o.WriteLine ();
106                 
107                 foreach (PropertyInfo pi in Comparer.Sort (t.GetProperties (flags))) {
108                         OutlineProperty (pi);
109                         
110                         o.WriteLine ();
111                 }
112                 
113                 o.WriteLine ();
114                 
115                 foreach (EventInfo ei in Comparer.Sort (t.GetEvents (flags))) {
116                         OutlineEvent (ei);
117                         
118                         o.WriteLine ();
119                 }
120
121                 o.WriteLine ();
122
123                 foreach (Type ntype in Comparer.Sort (t.GetNestedTypes (flags)))
124                         new Outline (ntype, o).OutlineType (flags);
125                 
126                 o.Indent--; o.WriteLine ("}");
127         }
128
129         void OutlineEvent (EventInfo ei)
130         {
131                 MethodBase accessor = ei.GetAddMethod ();
132                 
133                 o.Write (GetMethodVisibility (accessor));
134                 o.Write ("event ");
135                 o.Write (FormatType (ei.EventHandlerType));
136                 o.Write (" ");
137                 o.Write (ei.Name);
138                 o.Write (";");
139         }
140         
141         void OutlineConstructor (ConstructorInfo ci)
142         {
143                 o.Write (GetMethodVisibility (ci));
144                 o.Write (t.Name);
145                 o.Write (" (");
146                 OutlineParams (ci.GetParameters ());
147                 o.Write (");");
148         }
149         
150         
151         void OutlineProperty (PropertyInfo pi)
152         {
153                 ParameterInfo [] idxp = pi.GetIndexParameters ();
154                 MethodBase accessor = pi.CanRead ? pi.GetGetMethod (true) : pi.GetSetMethod (true);
155                 
156                 o.Write (GetMethodVisibility (accessor));
157                 o.Write (GetMethodModifiers  (accessor));
158                 o.Write (FormatType (pi.PropertyType));
159                 o.Write (" ");
160                 
161                 if (idxp.Length == 0)
162                         o.Write (pi.Name);
163                 else {
164                         o.Write ("this [");
165                         OutlineParams (idxp);
166                         o.Write ("]");
167                 }
168                 
169                 o.WriteLine (" {");
170                 o.Indent ++;
171                 
172                 if (pi.CanRead)  o.WriteLine ("get;");
173                 if (pi.CanWrite) o.WriteLine ("set;");
174                 
175                 o.Indent --;
176                 o.Write ("}");
177         }
178         
179         void OutlineMethod (MethodInfo mi)
180         {
181                 o.Write (GetMethodVisibility (mi));
182                 o.Write (GetMethodModifiers  (mi));
183                 o.Write (FormatType (mi.ReturnType));
184                 o.Write (" ");
185                 o.Write (mi.Name);
186                 o.Write (" (");
187                 OutlineParams (mi.GetParameters ());
188                 o.Write (");");
189         }
190         
191         void OutlineParams (ParameterInfo [] pi)
192         {
193                 int i = 0;
194                 foreach (ParameterInfo p in pi) {
195                         bool isPointer = false;
196                         if (p.ParameterType.IsByRef) {
197                                 o.Write (p.IsOut ? "out " : "ref ");
198                                 o.Write (FormatType (p.ParameterType.GetElementType ()));
199                         } else
200                                 o.Write (FormatType (p.ParameterType));
201                         
202                         o.Write (" ");
203                         o.Write (p.Name);
204                         if (i + 1 < pi.Length)
205                                 o.Write (", ");
206                         i++;
207                 }
208         }
209
210         static string GetMethodVisibility (MethodBase m)
211         {
212                 if (m.IsPublic)   return "public ";
213                 if (m.IsFamily)   return "protected ";
214                 if (m.IsPrivate)  return "private ";
215                 if (m.IsAssembly) return "internal ";
216                         
217                 return null;
218         }
219         
220         static string GetMethodModifiers (MethodBase method)
221         {
222                 if (method.IsStatic)
223                         return "static ";
224         
225                 if (method.IsVirtual)
226                         return ((method.Attributes & MethodAttributes.NewSlot) != 0) ?
227                                 "virtual " :
228                                 "override ";
229                 
230                 return null;
231         }
232
233         static string GetTypeKind (Type t)
234         {
235                 if (t.IsEnum)
236                         return "enum";
237                 if (t.IsClass) {
238                         if (t.IsSubclassOf (typeof (System.MulticastDelegate)))
239                                 return "delegate";
240                         else
241                                 return "class";
242                 }
243                 if (t.IsInterface)
244                         return "interface";
245                 if (t.IsValueType)
246                         return "struct";
247                 return "class";
248         }
249         
250         static string GetTypeVisibility (Type t)
251         {
252                 switch (t.Attributes & TypeAttributes.VisibilityMask){
253                 case TypeAttributes.Public:
254                 case TypeAttributes.NestedPublic:
255                         return "public";
256
257                 case TypeAttributes.NestedFamily:
258                 case TypeAttributes.NestedFamANDAssem:
259                 case TypeAttributes.NestedFamORAssem:
260                         return "protected";
261
262                 default:
263                         return "internal";
264                 }
265         }
266         
267         static string FormatType (Type t)
268         {
269                 string type = t.FullName;
270                 if (!type.StartsWith ("System."))
271                         return type;
272                 
273                 if (t.HasElementType) {
274                         Type et = t.GetElementType ();
275                         if (t.IsArray)
276                                 return FormatType (et) + " []";
277                         if (t.IsPointer)
278                                 return FormatType (et) + " *";
279                         if (t.IsByRef)
280                                 return "ref " + FormatType (et);
281                 }
282         
283                 switch (type) {
284                 case "System.Byte": return "byte";
285                 case "System.SByte": return "sbyte";
286                 case "System.Int16": return "short";
287                 case "System.Int32": return "int";
288                 case "System.Int64": return "long";
289                         
290                 case "System.UInt16": return "ushort";
291                 case "System.UInt32": return "uint";
292                 case "System.UInt64": return "ulong";
293                         
294                 case "System.Single":  return "float";
295                 case "System.Double":  return "double";
296                 case "System.Decimal": return "decimal";
297                 case "System.Boolean": return "bool";
298                 case "System.Char":    return "char";
299                 case "System.String":  return "string";
300                         
301                 case "System.Object":  return "object";
302                 case "System.Void":  return "void";
303                 }
304         
305                 if (type.LastIndexOf(".") == 6)
306                         return type.Substring(7);
307                 
308                 return type;
309         }
310 }
311
312 public class Comparer : IComparer  {
313         delegate int ComparerFunc (object a, object b);
314         
315         ComparerFunc cmp;
316         
317         Comparer (ComparerFunc f)
318         {
319                 this.cmp = f;
320         }
321         
322         public int Compare (object a, object b)
323         {
324                 return cmp (a, b);
325         }
326
327         static int CompareType (object a, object b)
328         {
329                 Type type1 = (Type) a;
330                 Type type2 = (Type) b;
331
332                 if (type1.IsSubclassOf (typeof (System.MulticastDelegate)) != type2.IsSubclassOf (typeof (System.MulticastDelegate)))
333                                 return (type1.IsSubclassOf (typeof (System.MulticastDelegate)))? -1:1;
334                 return string.Compare (type1.Name, type2.Name);
335                         
336         }
337
338         static Comparer TypeComparer = new Comparer (new ComparerFunc (CompareType));
339
340         static Type [] Sort (Type [] types)
341         {
342                 Array.Sort (types, TypeComparer);
343                 return types;
344         }
345         
346         static int CompareMemberInfo (object a, object b)
347         {
348                 return string.Compare (((MemberInfo) a).Name, ((MemberInfo) b).Name);
349         }
350         
351         static Comparer MemberInfoComparer = new Comparer (new ComparerFunc (CompareMemberInfo));
352         
353         public static MemberInfo [] Sort (MemberInfo [] inf)
354         {
355                 Array.Sort (inf, MemberInfoComparer);
356                 return inf;
357         }
358         
359         static int CompareMethodBase (object a, object b)
360         {
361                 MethodBase aa = (MethodBase) a, bb = (MethodBase) b;
362                 
363                 if (aa.IsStatic == bb.IsStatic)
364                         return CompareMemberInfo (a, b);
365                 
366                 if (aa.IsStatic)
367                         return -1;
368                 
369                 return 1;
370         }
371         
372         static Comparer MethodBaseComparer = new Comparer (new ComparerFunc (CompareMethodBase));
373         
374         public static MethodBase [] Sort (MethodBase [] inf)
375         {
376                 Array.Sort (inf, MethodBaseComparer);
377                 return inf;
378         }
379         
380         static int ComparePropertyInfo (object a, object b)
381         {
382                 PropertyInfo aa = (PropertyInfo) a, bb = (PropertyInfo) b;
383                 
384                 bool astatic = (aa.CanRead ? aa.GetGetMethod (true) : aa.GetSetMethod (true)).IsStatic;
385                 bool bstatic = (bb.CanRead ? bb.GetGetMethod (true) : bb.GetSetMethod (true)).IsStatic;
386                 
387                 if (astatic == bstatic)
388                         return CompareMemberInfo (a, b);
389                 
390                 if (astatic)
391                         return -1;
392                 
393                 return 1;
394         }
395         
396         static Comparer PropertyInfoComparer = new Comparer (new ComparerFunc (ComparePropertyInfo));
397         
398         public static PropertyInfo [] Sort (PropertyInfo [] inf)
399         {
400                 Array.Sort (inf, PropertyInfoComparer);
401                 return inf;
402         }
403         
404         static int CompareEventInfo (object a, object b)
405         {
406                 EventInfo aa = (EventInfo) a, bb = (EventInfo) b;
407                 
408                 bool astatic = aa.GetAddMethod (true).IsStatic;
409                 bool bstatic = bb.GetAddMethod (true).IsStatic;
410                 
411                 if (astatic == bstatic)
412                         return CompareMemberInfo (a, b);
413                 
414                 if (astatic)
415                         return -1;
416                 
417                 return 1;
418         }
419         
420         static Comparer EventInfoComparer = new Comparer (new ComparerFunc (CompareEventInfo));
421         
422         public static EventInfo [] Sort (EventInfo [] inf)
423         {
424                 Array.Sort (inf, EventInfoComparer);
425                 return inf;
426         }
427 }