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