Implemented better attribute support for C# output.
[mono.git] / mcs / tools / type-reflector / TypeDisplayer.cs
1 //
2 // TestDisplayer.cs: Base class for parsing Type objects.
3 //
4 // Author: Jonathan Pryor (jonpryor@vt.edu)
5 //
6 // (C) 2002 Jonathan Pryor
7 //
8 // Permission is hereby granted, free of charge, to any           
9 // person obtaining a copy of this software and associated        
10 // documentation files (the "Software"), to deal in the           
11 // Software without restriction, including without limitation     
12 // the rights to use, copy, modify, merge, publish,               
13 // distribute, sublicense, and/or sell copies of the Software,    
14 // and to permit persons to whom the Software is furnished to     
15 // do so, subject to the following conditions:                    
16 //                                                                 
17 // The above copyright notice and this permission notice          
18 // shall be included in all copies or substantial portions        
19 // of the Software.                                               
20 //                                                                 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY      
22 // KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO         
23 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A               
24 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL      
25 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,      
26 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  
27 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION       
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System;
32 using System.Collections;
33 using System.IO;
34 using System.Diagnostics;
35 using System.Reflection;
36 using System.Text;
37 using System.Text.RegularExpressions;
38
39 namespace Mono.TypeReflector
40 {
41         public delegate void BaseTypeEventHandler (object sender, BaseTypeEventArgs e);
42         public delegate void TypeEventHandler (object sender, TypeEventArgs e);
43         public delegate void InterfacesEventHandler (object sender, InterfacesEventArgs e);
44         public delegate void FieldsEventHandler (object sender, FieldsEventArgs e);
45         public delegate void PropertiesEventHandler (object sender, PropertiesEventArgs e);
46         public delegate void EventsEventHandler (object sender, EventsEventArgs e);
47         public delegate void ConstructorsEventHandler (object sender, ConstructorsEventArgs e);
48         public delegate void MethodsEventHandler (object sender, MethodsEventArgs e);
49
50         public class BaseTypeEventArgs : EventArgs {
51
52                 private Type _base;
53
54                 internal BaseTypeEventArgs (Type type)
55                 {
56                         _base = type;
57                 }
58
59                 public Type BaseType {
60                         get {return _base;}
61                 }
62         }
63
64         public class TypeEventArgs : EventArgs {
65
66                 private Type _type;
67
68                 internal TypeEventArgs (Type type)
69                 {
70                         _type = type;
71                 }
72
73                 public Type Type {
74                         get {return _type;}
75                 }
76         }
77
78         public class InterfacesEventArgs : EventArgs {
79
80                 private Type[] _interfaces;
81
82                 internal InterfacesEventArgs (Type[] interfaces)
83                 {
84                         _interfaces = interfaces ;
85                 }
86
87                 public Type[] Interfaces {
88                         get {return _interfaces;}
89                 }
90         }
91
92         public class FieldsEventArgs : EventArgs {
93                 private FieldInfo[] _fields;
94
95                 internal FieldsEventArgs (FieldInfo[] fields)
96                 {
97                         _fields = fields;
98                 }
99
100                 public FieldInfo[] Fields {
101                         get {return _fields;}
102                 }
103         }
104
105         public class PropertiesEventArgs : EventArgs {
106
107                 private PropertyInfo[] _props;
108
109                 internal PropertiesEventArgs (PropertyInfo[] properties)
110                 {
111                         _props = properties;
112                 }
113
114                 public PropertyInfo[] Properties {
115                         get {return _props;}
116                 }
117         }
118
119         public class EventsEventArgs : EventArgs {
120
121                 private EventInfo[] _events;
122
123                 internal EventsEventArgs (EventInfo[] events)
124                 {
125                         _events = events;
126                 }
127
128                 public EventInfo[] Events {
129                         get {return _events;}
130                 }
131         }
132
133         public class ConstructorsEventArgs : EventArgs {
134
135                 private ConstructorInfo[] _ctors;
136
137                 internal ConstructorsEventArgs (ConstructorInfo[] ctors)
138                 {
139                         _ctors = ctors;
140                 }
141
142                 public ConstructorInfo[] Constructors {
143                         get {return _ctors;}
144                 }
145         }
146
147         public class MethodsEventArgs : EventArgs {
148
149                 private MethodInfo[] _methods;
150
151                 internal MethodsEventArgs (MethodInfo[] methods)
152                 {
153                         _methods = methods;
154                 }
155
156                 public MethodInfo[] Methods {
157                         get {return _methods;}
158                 }
159         }
160
161         public class TypeDisplayer {
162
163                 private bool showBase = false;
164                 private bool showConstructors = false;
165                 private bool showEvents = false;
166                 private bool showFields = false;
167                 private bool showInterfaces = false;
168                 private bool showMethods = false;
169                 private bool showProperties = false;
170                 private bool showTypeProperties = false;
171                 private bool showInheritedMembers = false;
172                 private bool verboseOutput = false;
173                 private bool flattenHierarchy = false;
174                 private bool showNonPublic = false;
175                 private bool showMonoBroken = false;
176
177                 // `PrintTypeProperties' is recursive, but refrains from printing
178                 // duplicates.  Despite duplicate removal, the output for printing the
179                 // Properties of System.Type is > 800K of text.
180                 //
181                 // 3 levels permits viewing Attribute values, but not the attributes of
182                 // those attribute values.
183                 //
184                 // For example, 3 levels permits:
185                 //              class           System.Type                           {depth 0}
186                 //                      Properties:                                 {depth 1}
187                 //                              System.Reflection.MemberTypes MemberType  {depth 2}
188                 //                                      - CanRead=True                          {depth 3}
189                 //                                      - CanWrite=False                        {depth 3}
190                 //                                      ...
191                 private int maxDepth = 3;
192
193                 public TypeDisplayer ()
194                 {
195                 }
196
197                 public int MaxDepth {
198                         get {return maxDepth;}
199                         set {maxDepth = value;}
200                 }
201
202                 public bool ShowBase {
203                         get {return showBase;}
204                         set {showBase = value;}
205                 }
206
207                 public bool ShowConstructors {
208                         get {return showConstructors;}
209                         set {showConstructors = value;}
210                 }
211
212                 public bool ShowEvents {
213                         get {return showEvents;}
214                         set {showEvents = value;}
215                 }
216
217                 public bool ShowFields {
218                         get {return showFields;}
219                         set {showFields = value;}
220                 }
221
222                 public bool ShowInterfaces {
223                         get {return showInterfaces;}
224                         set {showInterfaces = value;}
225                 }
226
227                 public bool ShowMethods {
228                         get {return showMethods;}
229                         set {showMethods = value;}
230                 }
231
232                 public bool ShowProperties {
233                         get {return showProperties;}
234                         set {showProperties = value;}
235                 }
236
237                 public bool ShowTypeProperties {
238                         get {return showTypeProperties;}
239                         set {showTypeProperties = value;}
240                 }
241
242                 public bool ShowInheritedMembers {
243                         get {return showInheritedMembers;}
244                         set {showInheritedMembers = value;}
245                 }
246
247                 public bool ShowNonPublic {
248                         get {return showNonPublic;}
249                         set {showNonPublic = value;}
250                 }
251
252                 public bool ShowMonoBroken {
253                         get {return showMonoBroken;}
254                         set {showMonoBroken = value;}
255                 }
256
257                 public bool FlattenHierarchy {
258                         get {return flattenHierarchy;}
259                         set {flattenHierarchy = value;}
260                 }
261
262                 public bool VerboseOutput {
263                         get {return verboseOutput;}
264                         set {verboseOutput = value;}
265                 }
266
267                 private static BindingFlags bindingFlags = 
268                         BindingFlags.DeclaredOnly | 
269                         BindingFlags.Public | 
270                         BindingFlags.Instance | 
271                         BindingFlags.Static;
272
273                 public void Parse (Type type)
274                 {
275                         BindingFlags bf = bindingFlags;
276
277                         if (FlattenHierarchy)
278                                 bf |= BindingFlags.FlattenHierarchy;
279                         if (ShowInheritedMembers)
280                                 bf &= ~BindingFlags.DeclaredOnly;
281                         if (ShowNonPublic)
282                                 bf |= BindingFlags.NonPublic;
283
284                         OnTypeDeclaration (type);
285                         OnTypeBody (type, bf);
286                 }
287
288                 public static string FieldValue (FieldInfo f)
289                 {
290                         string s = null;
291                         if (f.DeclaringType.IsEnum)
292                                 s = String.Format ("0x{0}",
293                                                 Enum.Format (f.DeclaringType, f.GetValue (null), "x"));
294                         else
295                                 s = f.GetValue(null).ToString();
296                         return s;
297                 }
298
299                 protected virtual void OnTypeDeclaration (Type type)
300                 {
301                         Type (type);
302
303                         BaseType (type.BaseType);
304                         Interfaces (type.GetInterfaces ());
305                 }
306
307                 protected virtual void OnTypeBody (Type type, BindingFlags bf)
308                 {
309                         Fields (type.GetFields(bf));
310                         Constructors (type.GetConstructors(bf));
311                         Properties (type.GetProperties(bf));
312                         Events (type.GetEvents(bf));
313                         Methods (type.GetMethods(bf));
314                 }
315
316                 private void Type (Type t)
317                 {
318                         TypeEventArgs ea = new TypeEventArgs (t);
319                         try {
320                                 OnType (ea);
321                         } finally {
322                                 if (ReceiveTypes != null)
323                                         ReceiveTypes (this, ea);
324                         }
325                 }
326
327                 protected virtual void OnType (TypeEventArgs e) {}
328
329                 private void BaseType (Type t)
330                 {
331                         if (ShowBase) {
332                                 BaseTypeEventArgs ea = new BaseTypeEventArgs (t);
333                                 try {
334                                         OnBaseType (ea);
335                                 } finally {
336                                         if (ReceiveBaseType != null)
337                                                 ReceiveBaseType (this, ea);
338                                 }
339                         }
340                 }
341
342                 protected virtual void OnBaseType (BaseTypeEventArgs e) {}
343
344                 private void Interfaces (Type[] i)
345                 {
346                         if (ShowInterfaces) {
347                                 InterfacesEventArgs ea = new InterfacesEventArgs (i);
348                                 try {
349                                         OnInterfaces (ea);
350                                 } finally {
351                                         if (ReceiveInterfaces != null)
352                                                 ReceiveInterfaces (this, ea);
353                                 }
354                         }
355                 }
356
357                 protected virtual void OnInterfaces (InterfacesEventArgs e) {}
358
359                 private void Fields (FieldInfo[] f)
360                 {
361                         if (ShowFields) {
362                                 FieldsEventArgs ea = new FieldsEventArgs (f);
363                                 try {
364                                         OnFields (ea);
365                                 } finally {
366                                         if (ReceiveFields != null)
367                                                 ReceiveFields (this, ea);
368                                 }
369                         }
370                 }
371
372                 protected virtual void OnFields (FieldsEventArgs e) {}
373
374                 private void Properties (PropertyInfo[] p)
375                 {
376                         if (ShowProperties) {
377                                 PropertiesEventArgs ea = new PropertiesEventArgs (p);
378                                 try {
379                                         OnProperties (ea);
380                                 } finally {
381                                         if (ReceiveProperties != null)
382                                                 ReceiveProperties (this, ea);
383                                 }
384                         }
385                 }
386
387                 protected virtual void OnProperties (PropertiesEventArgs e) {}
388
389                 private void Events (EventInfo[] e)
390                 {
391                         if (ShowEvents) {
392                                 EventsEventArgs ea = new EventsEventArgs (e);
393                                 try {
394                                         OnEvents (ea);
395                                 } finally {
396                                         if (ReceiveEvents != null)
397                                                 ReceiveEvents (this, ea);
398                                 }
399                         }
400                 }
401
402                 protected virtual void OnEvents (EventsEventArgs e) {}
403
404                 private void Constructors (ConstructorInfo[] c)
405                 {
406                         if (ShowConstructors) {
407                                 ConstructorsEventArgs ea = new ConstructorsEventArgs (c);
408                                 try {
409                                         OnConstructors (ea);
410                                 } finally {
411                                         if (ReceiveConstructors != null)
412                                                 ReceiveConstructors (this, ea);
413                                 }
414                         }
415                 }
416
417                 protected virtual void OnConstructors (ConstructorsEventArgs e)
418                 {
419                 }
420
421                 private void Methods (MethodInfo[] m)
422                 {
423                         if (ShowMethods) {
424                                 MethodsEventArgs ea = new MethodsEventArgs (m);
425                                 try {
426                                         OnMethods (ea);
427                                 } finally {
428                                         if (ReceiveMethods != null)
429                                                 ReceiveMethods (this, ea);
430                                 }
431                         }
432                 }
433
434                 protected virtual void OnMethods (MethodsEventArgs e) {}
435
436                 protected static string GetEnumDescription (Type enumType, object value)
437                 {
438                         StringBuilder sb = new StringBuilder ();
439                         sb.Append (Enum.Format(enumType, value, "f"));
440                         sb.Append (" (");
441                         try {
442                                 sb.Append (String.Format ("0x{0}", Enum.Format (enumType, value, "x")));
443                         }
444                         catch {
445                                 sb.Append ("<unable to determine enumeration value>");
446                         }
447                         sb.Append (")");
448                         return sb.ToString ();
449                 }
450
451                 protected static string GetTypeKeyword (Type type)
452                 {
453                         string t = null;
454
455                         if (type.IsClass)
456                                 t = "class";
457                         else if (type.IsEnum)
458                                 t = "enum";
459                         else if (type.IsValueType)
460                                 t = "struct";
461                         else if (type.IsInterface)
462                                 t = "interface";
463                         else
464                                 t = "type";
465
466                         return t;
467                 }
468
469                 protected static string GetTypeHeader (Type type)
470                 {
471                         return String.Format ("{0,-11}{1}", GetTypeKeyword (type), type.ToString());
472                 }
473
474                 public event TypeEventHandler         ReceiveTypes;
475                 public event BaseTypeEventHandler     ReceiveBaseType;
476                 public event InterfacesEventHandler   ReceiveInterfaces;
477                 public event FieldsEventHandler       ReceiveFields;
478                 public event PropertiesEventHandler   ReceiveProperties;
479                 public event EventsEventHandler       ReceiveEvents;
480                 public event ConstructorsEventHandler ReceiveConstructors;
481                 public event MethodsEventHandler      ReceiveMethods;
482         }
483 }
484