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