2 // mono-api-info.cs - Dumps public assembly information to an xml file.
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Copyright (C) 2003-2005 Novell, Inc (http://www.novell.com)
11 using System.Collections;
12 using System.Globalization;
13 using System.Reflection;
14 using System.Runtime.InteropServices;
15 using System.Security.Permissions;
19 namespace Mono.AssemblyInfo
23 static int Main (string [] args)
28 AssemblyCollection acoll = new AssemblyCollection ();
30 foreach (string fullName in args) {
34 XmlDocument doc = new XmlDocument ();
38 XmlTextWriter writer = new XmlTextWriter (Console.Out);
39 writer.Formatting = Formatting.Indented;
40 XmlNode decl = doc.CreateXmlDeclaration ("1.0", null, null);
41 doc.InsertBefore (decl, doc.DocumentElement);
47 class AssemblyCollection
52 public AssemblyCollection ()
54 assemblies = new ArrayList ();
57 public bool Add (string name)
59 Assembly ass = LoadAssembly (name);
67 public void DoOutput ()
70 throw new InvalidOperationException ("Document not set");
72 XmlNode nassemblies = document.CreateElement ("assemblies", null);
73 document.AppendChild (nassemblies);
74 foreach (Assembly a in assemblies) {
75 AssemblyData data = new AssemblyData (document, nassemblies, a);
80 public XmlDocument Document {
81 set { document = value; }
84 static Assembly LoadAssembly (string aname)
89 if (!name.EndsWith (".dll"))
91 ass = Assembly.LoadFrom (name);
96 ass = Assembly.LoadWithPartialName (aname);
104 abstract class BaseData
106 protected XmlDocument document;
107 protected XmlNode parent;
109 protected BaseData (XmlDocument doc, XmlNode parent)
112 this.parent = parent;
115 public abstract void DoOutput ();
117 protected void AddAttribute (XmlNode node, string name, string value)
119 XmlAttribute attr = document.CreateAttribute (name);
121 node.Attributes.Append (attr);
125 class AssemblyData : BaseData
129 public AssemblyData (XmlDocument document, XmlNode parent, Assembly ass)
130 : base (document, parent)
135 public override void DoOutput ()
137 if (document == null)
138 throw new InvalidOperationException ("Document not set");
140 XmlNode nassembly = document.CreateElement ("assembly", null);
141 AssemblyName aname = ass.GetName ();
142 AddAttribute (nassembly, "name", aname.Name);
143 AddAttribute (nassembly, "version", aname.Version.ToString ());
144 parent.AppendChild (nassembly);
145 AttributeData.OutputAttributes (document, nassembly, ass.GetCustomAttributes (false));
146 Type [] types = ass.GetExportedTypes ();
147 if (types == null || types.Length == 0)
150 Array.Sort (types, TypeComparer.Default);
152 XmlNode nss = document.CreateElement ("namespaces", null);
153 nassembly.AppendChild (nss);
155 string currentNS = "$%&$&";
157 XmlNode classes = null;
158 foreach (Type t in types) {
159 if (t.Namespace == null || t.Namespace == "")
165 if (t.IsNestedPublic || t.IsNestedAssembly || t.IsNestedFamANDAssem ||
166 t.IsNestedFamORAssem || t.IsNestedPrivate)
169 if (t.DeclaringType != null)
170 continue; // enforce !nested
172 if (t.Namespace != currentNS) {
173 currentNS = t.Namespace;
174 ns = document.CreateElement ("namespace", null);
175 AddAttribute (ns, "name", currentNS);
176 nss.AppendChild (ns);
177 classes = document.CreateElement ("classes", null);
178 ns.AppendChild (classes);
181 TypeData bd = new TypeData (document, classes, t);
187 abstract class MemberData : BaseData
189 MemberInfo [] members;
191 public MemberData (XmlDocument document, XmlNode parent, MemberInfo [] members)
192 : base (document, parent)
194 this.members = members;
197 public override void DoOutput ()
199 XmlNode mclass = document.CreateElement (ParentTag, null);
200 parent.AppendChild (mclass);
202 foreach (MemberInfo member in members) {
203 XmlNode mnode = document.CreateElement (Tag, null);
204 mclass.AppendChild (mnode);
205 AddAttribute (mnode, "name", GetName (member));
206 if (!NoMemberAttributes)
207 AddAttribute (mnode, "attrib", GetMemberAttributes (member));
209 AttributeData.OutputAttributes (document, mnode,
210 member.GetCustomAttributes (false));
212 AddExtraData (mnode, member);
216 protected virtual void AddExtraData (XmlNode p, MemberInfo member)
220 protected virtual string GetName (MemberInfo member)
225 protected virtual string GetMemberAttributes (MemberInfo member)
230 public virtual bool NoMemberAttributes {
231 get { return false; }
235 public virtual string ParentTag {
236 get { return "NoPARENTTAG"; }
239 public virtual string Tag {
240 get { return "NoTAG"; }
244 class TypeData : MemberData
247 const BindingFlags flags = BindingFlags.Public | BindingFlags.Static |
248 BindingFlags.Instance | BindingFlags.DeclaredOnly |
249 BindingFlags.NonPublic;
251 public TypeData (XmlDocument document, XmlNode parent, Type type)
252 : base (document, parent, null)
257 public override void DoOutput ()
259 if (document == null)
260 throw new InvalidOperationException ("Document not set");
262 XmlNode nclass = document.CreateElement ("class", null);
263 AddAttribute (nclass, "name", type.Name);
264 string classType = GetClassType (type);
265 AddAttribute (nclass, "type", classType);
267 if (type.BaseType != null)
268 AddAttribute (nclass, "base", type.BaseType.ToString ());
271 AddAttribute (nclass, "sealed", "true");
274 AddAttribute (nclass, "abstract", "true");
276 if (type.IsSerializable)
277 AddAttribute (nclass, "serializable", "true");
279 string charSet = GetCharSet (type);
280 AddAttribute (nclass, "charset", charSet);
282 string layout = GetLayout (type);
284 AddAttribute (nclass, "layout", layout);
286 parent.AppendChild (nclass);
288 AttributeData.OutputAttributes (document, nclass, type.GetCustomAttributes (false));
290 Type [] interfaces = type.GetInterfaces ();
291 if (interfaces != null && interfaces.Length > 0) {
292 XmlNode ifaces = document.CreateElement ("interfaces", null);
293 nclass.AppendChild (ifaces);
294 foreach (Type t in interfaces) {
296 // we're only interested in public interfaces
299 XmlNode iface = document.CreateElement ("interface", null);
300 AddAttribute (iface, "name", t.ToString ());
301 ifaces.AppendChild (iface);
306 // Generic constraints
307 Type [] gargs = type.GetGenericArguments ();
308 XmlElement ngeneric = (gargs.Length == 0) ? null :
309 document.CreateElement ("generic-type-constraints");
310 foreach (Type garg in gargs) {
311 Type [] csts = garg.GetGenericParameterConstraints ();
312 if (csts.Length == 0 || csts [0] == typeof (object))
314 XmlElement el = document.CreateElement ("generic-type-constraint");
315 el.SetAttribute ("name", garg.ToString ());
316 el.SetAttribute ("generic-attribute",
317 garg.GenericParameterAttributes.ToString ());
318 ngeneric.AppendChild (el);
319 foreach (Type ct in csts) {
320 XmlElement cel = document.CreateElement ("type");
321 cel.AppendChild (document.CreateTextNode (ct.FullName));
322 el.AppendChild (cel);
325 if (ngeneric != null && ngeneric.FirstChild != null)
326 nclass.AppendChild (ngeneric);
329 ArrayList members = new ArrayList ();
331 FieldInfo[] fields = GetFields (type);
332 if (fields.Length > 0) {
333 Array.Sort (fields, MemberInfoComparer.Default);
334 FieldData fd = new FieldData (document, nclass, fields);
335 // Special case for enum fields
336 if (classType == "enum") {
337 string etype = fields [0].GetType ().ToString ();
338 AddAttribute (nclass, "enumtype", etype);
343 ConstructorInfo [] ctors = GetConstructors (type);
344 if (ctors.Length > 0) {
345 Array.Sort (ctors, MemberInfoComparer.Default);
346 members.Add (new ConstructorData (document, nclass, ctors));
349 PropertyInfo[] properties = GetProperties (type);
350 if (properties.Length > 0) {
351 Array.Sort (properties, MemberInfoComparer.Default);
352 members.Add (new PropertyData (document, nclass, properties));
355 EventInfo [] events = GetEvents (type);
356 if (events.Length > 0) {
357 Array.Sort (events, MemberInfoComparer.Default);
358 members.Add (new EventData (document, nclass, events));
361 MethodInfo [] methods = GetMethods (type);
362 if (methods.Length > 0) {
363 Array.Sort (methods, MemberInfoComparer.Default);
364 members.Add (new MethodData (document, nclass, methods));
367 foreach (MemberData md in members)
370 Type [] nested = type.GetNestedTypes ();
371 if (nested != null && nested.Length > 0) {
372 XmlNode classes = document.CreateElement ("classes", null);
373 nclass.AppendChild (classes);
374 foreach (Type t in nested) {
375 TypeData td = new TypeData (document, classes, t);
381 protected override string GetMemberAttributes (MemberInfo member)
384 throw new InvalidOperationException ("odd");
386 return ((int) type.Attributes).ToString (CultureInfo.InvariantCulture);
389 public static bool MustDocumentMethod(MethodBase method)
392 return (method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly);
395 static string GetClassType (Type t)
406 if (typeof (Delegate).IsAssignableFrom (t))
412 private static string GetCharSet (Type type)
414 if (type.IsAnsiClass)
415 return CharSet.Ansi.ToString (CultureInfo.InvariantCulture);
417 if (type.IsAutoClass)
418 return CharSet.Auto.ToString (CultureInfo.InvariantCulture);
420 if (type.IsUnicodeClass)
421 return CharSet.Unicode.ToString (CultureInfo.InvariantCulture);
423 return CharSet.None.ToString (CultureInfo.InvariantCulture);
426 private static string GetLayout (Type type)
428 if (type.IsAutoLayout)
429 return LayoutKind.Auto.ToString (CultureInfo.InvariantCulture);
431 if (type.IsExplicitLayout)
432 return LayoutKind.Explicit.ToString (CultureInfo.InvariantCulture);
434 if (type.IsLayoutSequential)
435 return LayoutKind.Sequential.ToString (CultureInfo.InvariantCulture);
440 private FieldInfo[] GetFields (Type type)
442 ArrayList list = new ArrayList ();
444 FieldInfo[] fields = type.GetFields (flags);
445 foreach (FieldInfo field in fields) {
446 if (field.IsSpecialName)
449 // we're only interested in public or protected members
450 if (!field.IsPublic && !field.IsFamily && !field.IsFamilyOrAssembly)
456 return (FieldInfo[]) list.ToArray (typeof (FieldInfo));
459 internal static PropertyInfo[] GetProperties (Type type)
461 ArrayList list = new ArrayList ();
463 PropertyInfo[] properties = type.GetProperties (flags);
464 foreach (PropertyInfo property in properties) {
465 MethodInfo getMethod = null;
466 MethodInfo setMethod = null;
468 if (property.CanRead) {
469 try { getMethod = property.GetGetMethod (true); }
470 catch (System.Security.SecurityException) { }
472 if (property.CanWrite) {
473 try { setMethod = property.GetSetMethod (true); }
474 catch (System.Security.SecurityException) { }
477 bool hasGetter = (getMethod != null) && MustDocumentMethod (getMethod);
478 bool hasSetter = (setMethod != null) && MustDocumentMethod (setMethod);
480 // if neither the getter or setter should be documented, then
482 if (!hasGetter && !hasSetter) {
489 return (PropertyInfo[]) list.ToArray (typeof (PropertyInfo));
492 private MethodInfo[] GetMethods (Type type)
494 ArrayList list = new ArrayList ();
496 MethodInfo[] methods = type.GetMethods (flags);
497 foreach (MethodInfo method in methods) {
498 if (method.IsSpecialName)
501 // we're only interested in public or protected members
502 if (!MustDocumentMethod(method))
508 return (MethodInfo[]) list.ToArray (typeof (MethodInfo));
511 private ConstructorInfo[] GetConstructors (Type type)
513 ArrayList list = new ArrayList ();
515 ConstructorInfo[] ctors = type.GetConstructors (flags);
516 foreach (ConstructorInfo constructor in ctors) {
517 // we're only interested in public or protected members
518 if (!constructor.IsPublic && !constructor.IsFamily && !constructor.IsFamilyOrAssembly)
521 list.Add (constructor);
524 return (ConstructorInfo[]) list.ToArray (typeof (ConstructorInfo));
527 private EventInfo[] GetEvents (Type type)
529 ArrayList list = new ArrayList ();
531 EventInfo[] events = type.GetEvents (flags);
532 foreach (EventInfo eventInfo in events) {
533 MethodInfo addMethod = eventInfo.GetAddMethod (true);
535 if (addMethod == null || !MustDocumentMethod (addMethod))
538 list.Add (eventInfo);
541 return (EventInfo[]) list.ToArray (typeof (EventInfo));
545 class FieldData : MemberData
547 public FieldData (XmlDocument document, XmlNode parent, FieldInfo [] members)
548 : base (document, parent, members)
552 protected override string GetName (MemberInfo member)
554 FieldInfo field = (FieldInfo) member;
558 protected override string GetMemberAttributes (MemberInfo member)
560 FieldInfo field = (FieldInfo) member;
561 return ((int) field.Attributes).ToString (CultureInfo.InvariantCulture);
564 protected override void AddExtraData (XmlNode p, MemberInfo member)
566 base.AddExtraData (p, member);
567 FieldInfo field = (FieldInfo) member;
568 AddAttribute (p, "fieldtype", field.FieldType.ToString ());
570 if (field.IsLiteral) {
571 object value = field.GetValue (null);
572 string stringValue = null;
574 // FIXME: when Mono bug #60090 has been
575 // fixed, we should just be able to use
577 stringValue = ((Enum) value).ToString ("D", CultureInfo.InvariantCulture);
579 stringValue = Convert.ToString (value, CultureInfo.InvariantCulture);
582 if (stringValue != null)
583 AddAttribute (p, "value", stringValue);
587 public override string ParentTag {
588 get { return "fields"; }
591 public override string Tag {
592 get { return "field"; }
596 class PropertyData : MemberData
598 public PropertyData (XmlDocument document, XmlNode parent, PropertyInfo [] members)
599 : base (document, parent, members)
603 protected override string GetName (MemberInfo member)
605 PropertyInfo prop = (PropertyInfo) member;
609 protected override void AddExtraData (XmlNode p, MemberInfo member)
611 base.AddExtraData (p, member);
612 PropertyInfo prop = (PropertyInfo) member;
613 Type t = prop.PropertyType;
614 AddAttribute (p, "ptype", prop.PropertyType.ToString ());
615 MethodInfo _get = prop.GetGetMethod (true);
616 MethodInfo _set = prop.GetSetMethod (true);
617 bool haveGet = (_get != null && TypeData.MustDocumentMethod(_get));
618 bool haveSet = (_set != null && TypeData.MustDocumentMethod(_set));
619 MethodInfo [] methods;
621 if (haveGet && haveSet) {
622 methods = new MethodInfo [] {_get, _set};
623 } else if (haveGet) {
624 methods = new MethodInfo [] {_get};
625 } else if (haveSet) {
626 methods = new MethodInfo [] {_set};
632 string parms = Parameters.GetSignature (methods [0].GetParameters ());
633 AddAttribute (p, "params", parms);
635 MethodData data = new MethodData (document, p, methods);
636 //data.NoMemberAttributes = true;
640 protected override string GetMemberAttributes (MemberInfo member)
642 PropertyInfo prop = (PropertyInfo) member;
643 return ((int) prop.Attributes & (0xFFFFFFFF ^ (int) PropertyAttributes.ReservedMask)).ToString (CultureInfo.InvariantCulture);
646 public override string ParentTag {
647 get { return "properties"; }
650 public override string Tag {
651 get { return "property"; }
655 class EventData : MemberData
657 public EventData (XmlDocument document, XmlNode parent, EventInfo [] members)
658 : base (document, parent, members)
662 protected override string GetName (MemberInfo member)
664 EventInfo evt = (EventInfo) member;
668 protected override string GetMemberAttributes (MemberInfo member)
670 EventInfo evt = (EventInfo) member;
671 return ((int) evt.Attributes).ToString (CultureInfo.InvariantCulture);
674 protected override void AddExtraData (XmlNode p, MemberInfo member)
676 base.AddExtraData (p, member);
677 EventInfo evt = (EventInfo) member;
678 AddAttribute (p, "eventtype", evt.EventHandlerType.ToString ());
681 public override string ParentTag {
682 get { return "events"; }
685 public override string Tag {
686 get { return "event"; }
690 class MethodData : MemberData
694 public MethodData (XmlDocument document, XmlNode parent, MethodBase [] members)
695 : base (document, parent, members)
699 protected override string GetName (MemberInfo member)
701 MethodBase method = (MethodBase) member;
702 string name = method.Name;
703 string parms = Parameters.GetSignature (method.GetParameters ());
705 MethodInfo mi = method as MethodInfo;
706 Type [] genArgs = mi == null ? Type.EmptyTypes :
707 mi.GetGenericArguments ();
708 if (genArgs.Length > 0) {
709 string [] genArgNames = new string [genArgs.Length];
710 for (int i = 0; i < genArgs.Length; i++) {
711 genArgNames [i] = genArgs [i].Name;
712 string genArgCsts = String.Empty;
713 Type [] gcs = genArgs [i].GetGenericParameterConstraints ();
714 if (gcs.Length > 0) {
715 string [] gcNames = new string [gcs.Length];
716 for (int g = 0; g < gcs.Length; g++)
717 gcNames [g] = gcs [g].FullName;
718 genArgCsts = String.Concat (
720 string.Join (", ", gcNames),
725 genArgCsts = genArgNames [i];
726 if ((genArgs [i].GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
727 genArgCsts = "class " + genArgCsts;
728 else if ((genArgs [i].GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
729 genArgCsts = "struct " + genArgCsts;
730 genArgNames [i] = genArgCsts;
732 return String.Format ("{0}<{2}>({1})",
735 string.Join (",", genArgNames));
738 return String.Format ("{0}({1})", name, parms);
741 protected override string GetMemberAttributes (MemberInfo member)
743 MethodBase method = (MethodBase) member;
744 return ((int)( method.Attributes & ~MethodAttributes.ReservedMask)).ToString (CultureInfo.InvariantCulture);
747 protected override void AddExtraData (XmlNode p, MemberInfo member)
749 base.AddExtraData (p, member);
751 ParameterData parms = new ParameterData (document, p,
752 ((MethodBase) member).GetParameters ());
755 if (!(member is MethodBase))
758 MethodBase mbase = (MethodBase) member;
760 if (mbase.IsAbstract)
761 AddAttribute (p, "abstract", "true");
763 AddAttribute (p, "virtual", "true");
765 AddAttribute (p, "static", "true");
767 if (!(member is MethodInfo))
770 MethodInfo method = (MethodInfo) member;
771 AddAttribute (p, "returntype", method.ReturnType.ToString ());
773 AttributeData.OutputAttributes (document, p,
774 method.ReturnTypeCustomAttributes.GetCustomAttributes (false));
776 // Generic constraints
777 Type [] gargs = method.GetGenericArguments ();
778 XmlElement ngeneric = (gargs.Length == 0) ? null :
779 document.CreateElement ("generic-method-constraints");
780 foreach (Type garg in gargs) {
781 Type [] csts = garg.GetGenericParameterConstraints ();
782 if (csts.Length == 0 || csts [0] == typeof (object))
784 XmlElement el = document.CreateElement ("generic-method-constraint");
785 el.SetAttribute ("name", garg.ToString ());
786 el.SetAttribute ("generic-attribute",
787 garg.GenericParameterAttributes.ToString ());
788 ngeneric.AppendChild (el);
789 foreach (Type ct in csts) {
790 XmlElement cel = document.CreateElement ("type");
791 cel.AppendChild (document.CreateTextNode (ct.FullName));
792 el.AppendChild (cel);
795 if (ngeneric != null && ngeneric.FirstChild != null)
796 p.AppendChild (ngeneric);
801 public override bool NoMemberAttributes {
802 get { return noAtts; }
803 set { noAtts = value; }
806 public override string ParentTag {
807 get { return "methods"; }
810 public override string Tag {
811 get { return "method"; }
815 class ConstructorData : MethodData
817 public ConstructorData (XmlDocument document, XmlNode parent, ConstructorInfo [] members)
818 : base (document, parent, members)
822 public override string ParentTag {
823 get { return "constructors"; }
826 public override string Tag {
827 get { return "constructor"; }
831 class ParameterData : BaseData
833 private ParameterInfo[] parameters;
835 public ParameterData (XmlDocument document, XmlNode parent, ParameterInfo[] parameters)
836 : base (document, parent)
838 this.parameters = parameters;
841 public override void DoOutput ()
843 XmlNode parametersNode = document.CreateElement ("parameters", null);
844 parent.AppendChild (parametersNode);
846 foreach (ParameterInfo parameter in parameters) {
847 XmlNode paramNode = document.CreateElement ("parameter", null);
848 parametersNode.AppendChild (paramNode);
849 AddAttribute (paramNode, "name", parameter.Name);
850 AddAttribute (paramNode, "position", parameter.Position.ToString(CultureInfo.InvariantCulture));
851 AddAttribute (paramNode, "attrib", ((int) parameter.Attributes).ToString());
853 string direction = "in";
855 if (parameter.ParameterType.IsByRef) {
856 direction = parameter.IsOut ? "out" : "ref";
859 Type t = parameter.ParameterType;
860 AddAttribute (paramNode, "type", t.ToString ());
862 if (parameter.IsOptional) {
863 AddAttribute (paramNode, "optional", "true");
864 if (parameter.DefaultValue != System.DBNull.Value)
865 AddAttribute (paramNode, "defaultValue", (parameter.DefaultValue == null) ? "NULL" : parameter.DefaultValue.ToString ());
868 if (direction != "in")
869 AddAttribute (paramNode, "direction", direction);
871 AttributeData.OutputAttributes (document, paramNode, parameter.GetCustomAttributes (false));
876 class AttributeData : BaseData
880 AttributeData (XmlDocument doc, XmlNode parent, object[] attributes)
886 public override void DoOutput ()
888 if (document == null)
889 throw new InvalidOperationException ("Document not set");
891 if (atts == null || atts.Length == 0)
894 XmlNode natts = parent.SelectSingleNode("attributes");
896 natts = document.CreateElement ("attributes", null);
897 parent.AppendChild (natts);
900 for (int i = 0; i < atts.Length; ++i) {
901 Type t = atts [i].GetType ();
902 if (!t.IsPublic && !t.Name.EndsWith ("TODOAttribute"))
905 // we ignore attributes that inherit from SecurityAttribute on purpose as they:
906 // * aren't part of GetCustomAttributes in Fx 1.0/1.1;
907 // * are encoded differently and in a different metadata table; and
908 // * won't ever exactly match MS implementation (from a syntax pov)
909 if (t.IsSubclassOf (typeof (SecurityAttribute)))
912 XmlNode node = document.CreateElement ("attribute");
913 AddAttribute (node, "name", t.ToString ());
915 XmlNode properties = null;
916 foreach (PropertyInfo pi in TypeData.GetProperties (t)) {
917 if (pi.Name == "TypeId")
920 if (properties == null) {
921 properties = node.AppendChild (document.CreateElement ("properties"));
925 object o = pi.GetValue (atts [i], null);
927 XmlNode n = properties.AppendChild (document.CreateElement ("property"));
928 AddAttribute (n, "name", pi.Name);
931 AddAttribute (n, "null", "true");
935 string value = o.ToString ();
936 if (t == typeof (GuidAttribute))
937 value = value.ToUpper ();
939 AddAttribute (n, "value", value);
941 catch (TargetInvocationException) {
946 natts.AppendChild (node);
950 public static void OutputAttributes (XmlDocument doc, XmlNode parent, object[] attributes)
952 AttributeData ad = new AttributeData (doc, parent, attributes);
956 private static bool MustDocumentAttribute (Type attributeType)
958 // only document MonoTODOAttribute and public attributes
959 return attributeType.Name.EndsWith ("TODOAttribute") || attributeType.IsPublic;
965 private Parameters () {}
967 public static string GetSignature (ParameterInfo [] infos)
969 if (infos == null || infos.Length == 0)
972 StringBuilder sb = new StringBuilder ();
973 foreach (ParameterInfo info in infos) {
977 else if (info.IsRetval)
984 string type_name = info.ParameterType.ToString ().Replace ('<', '[').Replace ('>', ']');
985 sb.AppendFormat ("{0}{1}, ", modifier, type_name);
988 sb.Length -= 2; // remove ", "
989 return sb.ToString ();
994 class TypeComparer : IComparer
996 public static TypeComparer Default = new TypeComparer ();
998 public int Compare (object a, object b)
1002 int result = String.Compare (ta.Namespace, tb.Namespace);
1006 return String.Compare (ta.Name, tb.Name);
1010 class MemberInfoComparer : IComparer
1012 public static MemberInfoComparer Default = new MemberInfoComparer ();
1014 public int Compare (object a, object b)
1016 MemberInfo ma = (MemberInfo) a;
1017 MemberInfo mb = (MemberInfo) b;
1018 return String.Compare (ma.Name, mb.Name);
1022 class MethodBaseComparer : IComparer
1024 public static MethodBaseComparer Default = new MethodBaseComparer ();
1026 public int Compare (object a, object b)
1028 MethodBase ma = (MethodBase) a;
1029 MethodBase mb = (MethodBase) b;
1030 int res = String.Compare (ma.Name, mb.Name);
1034 ParameterInfo [] pia = ma.GetParameters ();
1035 ParameterInfo [] pib = mb.GetParameters ();
1036 if (pia.Length != pib.Length)
1037 return pia.Length - pib.Length;
1039 string siga = Parameters.GetSignature (pia);
1040 string sigb = Parameters.GetSignature (pib);
1041 return String.Compare (siga, sigb);