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);
124 public static bool IsMonoTODOAttribute (string s)
128 if (//s.EndsWith ("MonoTODOAttribute") ||
129 s.EndsWith ("MonoDocumentationNoteAttribute") ||
130 s.EndsWith ("MonoExtensionAttribute") ||
131 // s.EndsWith ("MonoInternalNoteAttribute") ||
132 s.EndsWith ("MonoLimitationAttribute") ||
133 s.EndsWith ("MonoNotSupportedAttribute"))
135 return s.EndsWith ("TODOAttribute");
139 class AssemblyData : BaseData
143 public AssemblyData (XmlDocument document, XmlNode parent, Assembly ass)
144 : base (document, parent)
149 public override void DoOutput ()
151 if (document == null)
152 throw new InvalidOperationException ("Document not set");
154 XmlNode nassembly = document.CreateElement ("assembly", null);
155 AssemblyName aname = ass.GetName ();
156 AddAttribute (nassembly, "name", aname.Name);
157 AddAttribute (nassembly, "version", aname.Version.ToString ());
158 parent.AppendChild (nassembly);
159 AttributeData.OutputAttributes (document, nassembly, ass.GetCustomAttributes (false));
160 Type [] types = ass.GetExportedTypes ();
161 if (types == null || types.Length == 0)
164 Array.Sort (types, TypeComparer.Default);
166 XmlNode nss = document.CreateElement ("namespaces", null);
167 nassembly.AppendChild (nss);
169 string currentNS = "$%&$&";
171 XmlNode classes = null;
172 foreach (Type t in types) {
173 if (t.Namespace == null || t.Namespace == "")
179 if (t.IsNestedPublic || t.IsNestedAssembly || t.IsNestedFamANDAssem ||
180 t.IsNestedFamORAssem || t.IsNestedPrivate)
183 if (t.DeclaringType != null)
184 continue; // enforce !nested
186 if (t.Namespace != currentNS) {
187 currentNS = t.Namespace;
188 ns = document.CreateElement ("namespace", null);
189 AddAttribute (ns, "name", currentNS);
190 nss.AppendChild (ns);
191 classes = document.CreateElement ("classes", null);
192 ns.AppendChild (classes);
195 TypeData bd = new TypeData (document, classes, t);
201 abstract class MemberData : BaseData
203 MemberInfo [] members;
205 public MemberData (XmlDocument document, XmlNode parent, MemberInfo [] members)
206 : base (document, parent)
208 this.members = members;
211 public override void DoOutput ()
213 XmlNode mclass = document.CreateElement (ParentTag, null);
214 parent.AppendChild (mclass);
216 foreach (MemberInfo member in members) {
217 XmlNode mnode = document.CreateElement (Tag, null);
218 mclass.AppendChild (mnode);
219 AddAttribute (mnode, "name", GetName (member));
220 if (!NoMemberAttributes)
221 AddAttribute (mnode, "attrib", GetMemberAttributes (member));
223 AttributeData.OutputAttributes (document, mnode,
224 member.GetCustomAttributes (false));
226 AddExtraData (mnode, member);
230 protected virtual void AddExtraData (XmlNode p, MemberInfo member)
234 protected virtual string GetName (MemberInfo member)
239 protected virtual string GetMemberAttributes (MemberInfo member)
244 public virtual bool NoMemberAttributes {
245 get { return false; }
249 public virtual string ParentTag {
250 get { return "NoPARENTTAG"; }
253 public virtual string Tag {
254 get { return "NoTAG"; }
258 class TypeData : MemberData
261 const BindingFlags flags = BindingFlags.Public | BindingFlags.Static |
262 BindingFlags.Instance | BindingFlags.DeclaredOnly |
263 BindingFlags.NonPublic;
265 public TypeData (XmlDocument document, XmlNode parent, Type type)
266 : base (document, parent, null)
271 public override void DoOutput ()
273 if (document == null)
274 throw new InvalidOperationException ("Document not set");
276 XmlNode nclass = document.CreateElement ("class", null);
277 AddAttribute (nclass, "name", type.Name);
278 string classType = GetClassType (type);
279 AddAttribute (nclass, "type", classType);
281 if (type.BaseType != null)
282 AddAttribute (nclass, "base", type.BaseType.ToString ());
285 AddAttribute (nclass, "sealed", "true");
288 AddAttribute (nclass, "abstract", "true");
290 if (type.IsSerializable)
291 AddAttribute (nclass, "serializable", "true");
293 string charSet = GetCharSet (type);
294 AddAttribute (nclass, "charset", charSet);
296 string layout = GetLayout (type);
298 AddAttribute (nclass, "layout", layout);
300 parent.AppendChild (nclass);
302 AttributeData.OutputAttributes (document, nclass, type.GetCustomAttributes (false));
304 Type [] interfaces = type.GetInterfaces ();
305 if (interfaces != null && interfaces.Length > 0) {
306 XmlNode ifaces = document.CreateElement ("interfaces", null);
307 nclass.AppendChild (ifaces);
308 foreach (Type t in interfaces) {
310 // we're only interested in public interfaces
313 XmlNode iface = document.CreateElement ("interface", null);
314 AddAttribute (iface, "name", t.ToString ());
315 ifaces.AppendChild (iface);
320 // Generic constraints
321 Type [] gargs = type.GetGenericArguments ();
322 XmlElement ngeneric = (gargs.Length == 0) ? null :
323 document.CreateElement ("generic-type-constraints");
324 foreach (Type garg in gargs) {
325 Type [] csts = garg.GetGenericParameterConstraints ();
326 if (csts.Length == 0 || csts [0] == typeof (object))
328 XmlElement el = document.CreateElement ("generic-type-constraint");
329 el.SetAttribute ("name", garg.ToString ());
330 el.SetAttribute ("generic-attribute",
331 garg.GenericParameterAttributes.ToString ());
332 ngeneric.AppendChild (el);
333 foreach (Type ct in csts) {
334 XmlElement cel = document.CreateElement ("type");
335 cel.AppendChild (document.CreateTextNode (ct.FullName));
336 el.AppendChild (cel);
339 if (ngeneric != null && ngeneric.FirstChild != null)
340 nclass.AppendChild (ngeneric);
343 ArrayList members = new ArrayList ();
345 FieldInfo[] fields = GetFields (type);
346 if (fields.Length > 0) {
347 Array.Sort (fields, MemberInfoComparer.Default);
348 FieldData fd = new FieldData (document, nclass, fields);
349 // Special case for enum fields
350 if (classType == "enum") {
351 string etype = fields [0].GetType ().ToString ();
352 AddAttribute (nclass, "enumtype", etype);
357 ConstructorInfo [] ctors = GetConstructors (type);
358 if (ctors.Length > 0) {
359 Array.Sort (ctors, MemberInfoComparer.Default);
360 members.Add (new ConstructorData (document, nclass, ctors));
363 PropertyInfo[] properties = GetProperties (type);
364 if (properties.Length > 0) {
365 Array.Sort (properties, MemberInfoComparer.Default);
366 members.Add (new PropertyData (document, nclass, properties));
369 EventInfo [] events = GetEvents (type);
370 if (events.Length > 0) {
371 Array.Sort (events, MemberInfoComparer.Default);
372 members.Add (new EventData (document, nclass, events));
375 MethodInfo [] methods = GetMethods (type);
376 if (methods.Length > 0) {
377 Array.Sort (methods, MemberInfoComparer.Default);
378 members.Add (new MethodData (document, nclass, methods));
381 foreach (MemberData md in members)
384 Type [] nested = type.GetNestedTypes (BindingFlags.Public | BindingFlags.NonPublic);
385 if (nested != null && nested.Length > 0) {
386 bool add_nested = false;
387 foreach (Type t in nested) {
388 if (t.IsNestedPublic || t.IsNestedFamily || t.IsNestedFamORAssem) {
395 XmlNode classes = document.CreateElement ("classes", null);
396 nclass.AppendChild (classes);
397 foreach (Type t in nested) {
398 if (t.IsNestedPublic || t.IsNestedFamily || t.IsNestedFamORAssem) {
399 TypeData td = new TypeData (document, classes, t);
407 protected override string GetMemberAttributes (MemberInfo member)
410 throw new InvalidOperationException ("odd");
412 return ((int) type.Attributes).ToString (CultureInfo.InvariantCulture);
415 public static bool MustDocumentMethod(MethodBase method)
418 return (method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly);
421 static string GetClassType (Type t)
432 if (typeof (Delegate).IsAssignableFrom (t))
438 private static string GetCharSet (Type type)
440 if (type.IsAnsiClass)
441 return CharSet.Ansi.ToString (CultureInfo.InvariantCulture);
443 if (type.IsAutoClass)
444 return CharSet.Auto.ToString (CultureInfo.InvariantCulture);
446 if (type.IsUnicodeClass)
447 return CharSet.Unicode.ToString (CultureInfo.InvariantCulture);
449 return CharSet.None.ToString (CultureInfo.InvariantCulture);
452 private static string GetLayout (Type type)
454 if (type.IsAutoLayout)
455 return LayoutKind.Auto.ToString (CultureInfo.InvariantCulture);
457 if (type.IsExplicitLayout)
458 return LayoutKind.Explicit.ToString (CultureInfo.InvariantCulture);
460 if (type.IsLayoutSequential)
461 return LayoutKind.Sequential.ToString (CultureInfo.InvariantCulture);
466 private FieldInfo[] GetFields (Type type)
468 ArrayList list = new ArrayList ();
470 FieldInfo[] fields = type.GetFields (flags);
471 foreach (FieldInfo field in fields) {
472 if (field.IsSpecialName)
475 // we're only interested in public or protected members
476 if (!field.IsPublic && !field.IsFamily && !field.IsFamilyOrAssembly)
482 return (FieldInfo[]) list.ToArray (typeof (FieldInfo));
485 internal static PropertyInfo[] GetProperties (Type type)
487 ArrayList list = new ArrayList ();
489 PropertyInfo[] properties = type.GetProperties (flags);
490 foreach (PropertyInfo property in properties) {
491 MethodInfo getMethod = null;
492 MethodInfo setMethod = null;
494 if (property.CanRead) {
495 try { getMethod = property.GetGetMethod (true); }
496 catch (System.Security.SecurityException) { }
498 if (property.CanWrite) {
499 try { setMethod = property.GetSetMethod (true); }
500 catch (System.Security.SecurityException) { }
503 bool hasGetter = (getMethod != null) && MustDocumentMethod (getMethod);
504 bool hasSetter = (setMethod != null) && MustDocumentMethod (setMethod);
506 // if neither the getter or setter should be documented, then
508 if (!hasGetter && !hasSetter) {
515 return (PropertyInfo[]) list.ToArray (typeof (PropertyInfo));
518 private MethodInfo[] GetMethods (Type type)
520 ArrayList list = new ArrayList ();
522 MethodInfo[] methods = type.GetMethods (flags);
523 foreach (MethodInfo method in methods) {
524 if (method.IsSpecialName && !method.Name.StartsWith ("op_"))
527 // we're only interested in public or protected members
528 if (!MustDocumentMethod(method))
534 return (MethodInfo[]) list.ToArray (typeof (MethodInfo));
537 private ConstructorInfo[] GetConstructors (Type type)
539 ArrayList list = new ArrayList ();
541 ConstructorInfo[] ctors = type.GetConstructors (flags);
542 foreach (ConstructorInfo constructor in ctors) {
543 // we're only interested in public or protected members
544 if (!constructor.IsPublic && !constructor.IsFamily && !constructor.IsFamilyOrAssembly)
547 list.Add (constructor);
550 return (ConstructorInfo[]) list.ToArray (typeof (ConstructorInfo));
553 private EventInfo[] GetEvents (Type type)
555 ArrayList list = new ArrayList ();
557 EventInfo[] events = type.GetEvents (flags);
558 foreach (EventInfo eventInfo in events) {
559 MethodInfo addMethod = eventInfo.GetAddMethod (true);
561 if (addMethod == null || !MustDocumentMethod (addMethod))
564 list.Add (eventInfo);
567 return (EventInfo[]) list.ToArray (typeof (EventInfo));
571 class FieldData : MemberData
573 public FieldData (XmlDocument document, XmlNode parent, FieldInfo [] members)
574 : base (document, parent, members)
578 protected override string GetName (MemberInfo member)
580 FieldInfo field = (FieldInfo) member;
584 protected override string GetMemberAttributes (MemberInfo member)
586 FieldInfo field = (FieldInfo) member;
587 return ((int) field.Attributes).ToString (CultureInfo.InvariantCulture);
590 protected override void AddExtraData (XmlNode p, MemberInfo member)
592 base.AddExtraData (p, member);
593 FieldInfo field = (FieldInfo) member;
594 AddAttribute (p, "fieldtype", field.FieldType.ToString ());
596 if (field.IsLiteral) {
597 object value = field.GetValue (null);
598 string stringValue = null;
600 // FIXME: when Mono bug #60090 has been
601 // fixed, we should just be able to use
603 stringValue = ((Enum) value).ToString ("D", CultureInfo.InvariantCulture);
605 stringValue = Convert.ToString (value, CultureInfo.InvariantCulture);
608 if (stringValue != null)
609 AddAttribute (p, "value", stringValue);
613 public override string ParentTag {
614 get { return "fields"; }
617 public override string Tag {
618 get { return "field"; }
622 class PropertyData : MemberData
624 public PropertyData (XmlDocument document, XmlNode parent, PropertyInfo [] members)
625 : base (document, parent, members)
629 protected override string GetName (MemberInfo member)
631 PropertyInfo prop = (PropertyInfo) member;
635 protected override void AddExtraData (XmlNode p, MemberInfo member)
637 base.AddExtraData (p, member);
638 PropertyInfo prop = (PropertyInfo) member;
639 Type t = prop.PropertyType;
640 AddAttribute (p, "ptype", prop.PropertyType.ToString ());
641 MethodInfo _get = prop.GetGetMethod (true);
642 MethodInfo _set = prop.GetSetMethod (true);
643 bool haveGet = (_get != null && TypeData.MustDocumentMethod(_get));
644 bool haveSet = (_set != null && TypeData.MustDocumentMethod(_set));
645 MethodInfo [] methods;
647 if (haveGet && haveSet) {
648 methods = new MethodInfo [] {_get, _set};
649 } else if (haveGet) {
650 methods = new MethodInfo [] {_get};
651 } else if (haveSet) {
652 methods = new MethodInfo [] {_set};
658 string parms = Parameters.GetSignature (methods [0].GetParameters ());
659 AddAttribute (p, "params", parms);
661 MethodData data = new MethodData (document, p, methods);
662 //data.NoMemberAttributes = true;
666 protected override string GetMemberAttributes (MemberInfo member)
668 PropertyInfo prop = (PropertyInfo) member;
669 return ((int) prop.Attributes & (0xFFFFFFFF ^ (int) PropertyAttributes.ReservedMask)).ToString (CultureInfo.InvariantCulture);
672 public override string ParentTag {
673 get { return "properties"; }
676 public override string Tag {
677 get { return "property"; }
681 class EventData : MemberData
683 public EventData (XmlDocument document, XmlNode parent, EventInfo [] members)
684 : base (document, parent, members)
688 protected override string GetName (MemberInfo member)
690 EventInfo evt = (EventInfo) member;
694 protected override string GetMemberAttributes (MemberInfo member)
696 EventInfo evt = (EventInfo) member;
697 return ((int) evt.Attributes).ToString (CultureInfo.InvariantCulture);
700 protected override void AddExtraData (XmlNode p, MemberInfo member)
702 base.AddExtraData (p, member);
703 EventInfo evt = (EventInfo) member;
704 AddAttribute (p, "eventtype", evt.EventHandlerType.ToString ());
707 public override string ParentTag {
708 get { return "events"; }
711 public override string Tag {
712 get { return "event"; }
716 class MethodData : MemberData
720 public MethodData (XmlDocument document, XmlNode parent, MethodBase [] members)
721 : base (document, parent, members)
725 protected override string GetName (MemberInfo member)
727 MethodBase method = (MethodBase) member;
728 string name = method.Name;
729 string parms = Parameters.GetSignature (method.GetParameters ());
731 MethodInfo mi = method as MethodInfo;
732 Type [] genArgs = mi == null ? Type.EmptyTypes :
733 mi.GetGenericArguments ();
734 if (genArgs.Length > 0) {
735 string [] genArgNames = new string [genArgs.Length];
736 for (int i = 0; i < genArgs.Length; i++) {
737 genArgNames [i] = genArgs [i].Name;
738 string genArgCsts = String.Empty;
739 Type [] gcs = genArgs [i].GetGenericParameterConstraints ();
740 if (gcs.Length > 0) {
741 string [] gcNames = new string [gcs.Length];
742 for (int g = 0; g < gcs.Length; g++)
743 gcNames [g] = gcs [g].FullName;
744 genArgCsts = String.Concat (
746 string.Join (", ", gcNames),
751 genArgCsts = genArgNames [i];
752 if ((genArgs [i].GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
753 genArgCsts = "class " + genArgCsts;
754 else if ((genArgs [i].GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
755 genArgCsts = "struct " + genArgCsts;
756 genArgNames [i] = genArgCsts;
758 return String.Format ("{0}<{2}>({1})",
761 string.Join (",", genArgNames));
764 return String.Format ("{0}({1})", name, parms);
767 protected override string GetMemberAttributes (MemberInfo member)
769 MethodBase method = (MethodBase) member;
770 return ((int)( method.Attributes & ~MethodAttributes.ReservedMask)).ToString (CultureInfo.InvariantCulture);
773 protected override void AddExtraData (XmlNode p, MemberInfo member)
775 base.AddExtraData (p, member);
777 ParameterData parms = new ParameterData (document, p,
778 ((MethodBase) member).GetParameters ());
781 if (!(member is MethodBase))
784 MethodBase mbase = (MethodBase) member;
786 if (mbase.IsAbstract)
787 AddAttribute (p, "abstract", "true");
789 AddAttribute (p, "virtual", "true");
791 AddAttribute (p, "final", "true");
793 AddAttribute (p, "static", "true");
795 if (!(member is MethodInfo))
798 MethodInfo method = (MethodInfo) member;
799 AddAttribute (p, "returntype", method.ReturnType.ToString ());
801 AttributeData.OutputAttributes (document, p,
802 method.ReturnTypeCustomAttributes.GetCustomAttributes (false));
804 // Generic constraints
805 Type [] gargs = method.GetGenericArguments ();
806 XmlElement ngeneric = (gargs.Length == 0) ? null :
807 document.CreateElement ("generic-method-constraints");
808 foreach (Type garg in gargs) {
809 Type [] csts = garg.GetGenericParameterConstraints ();
810 if (csts.Length == 0 || csts [0] == typeof (object))
812 XmlElement el = document.CreateElement ("generic-method-constraint");
813 el.SetAttribute ("name", garg.ToString ());
814 el.SetAttribute ("generic-attribute",
815 garg.GenericParameterAttributes.ToString ());
816 ngeneric.AppendChild (el);
817 foreach (Type ct in csts) {
818 XmlElement cel = document.CreateElement ("type");
819 cel.AppendChild (document.CreateTextNode (ct.FullName));
820 el.AppendChild (cel);
823 if (ngeneric != null && ngeneric.FirstChild != null)
824 p.AppendChild (ngeneric);
829 public override bool NoMemberAttributes {
830 get { return noAtts; }
831 set { noAtts = value; }
834 public override string ParentTag {
835 get { return "methods"; }
838 public override string Tag {
839 get { return "method"; }
843 class ConstructorData : MethodData
845 public ConstructorData (XmlDocument document, XmlNode parent, ConstructorInfo [] members)
846 : base (document, parent, members)
850 public override string ParentTag {
851 get { return "constructors"; }
854 public override string Tag {
855 get { return "constructor"; }
859 class ParameterData : BaseData
861 private ParameterInfo[] parameters;
863 public ParameterData (XmlDocument document, XmlNode parent, ParameterInfo[] parameters)
864 : base (document, parent)
866 this.parameters = parameters;
869 public override void DoOutput ()
871 XmlNode parametersNode = document.CreateElement ("parameters", null);
872 parent.AppendChild (parametersNode);
874 foreach (ParameterInfo parameter in parameters) {
875 XmlNode paramNode = document.CreateElement ("parameter", null);
876 parametersNode.AppendChild (paramNode);
877 AddAttribute (paramNode, "name", parameter.Name);
878 AddAttribute (paramNode, "position", parameter.Position.ToString(CultureInfo.InvariantCulture));
879 AddAttribute (paramNode, "attrib", ((int) parameter.Attributes).ToString());
881 string direction = "in";
883 if (parameter.ParameterType.IsByRef) {
884 direction = parameter.IsOut ? "out" : "ref";
887 Type t = parameter.ParameterType;
888 AddAttribute (paramNode, "type", t.ToString ());
890 if (parameter.IsOptional) {
891 AddAttribute (paramNode, "optional", "true");
892 if (parameter.DefaultValue != System.DBNull.Value)
893 AddAttribute (paramNode, "defaultValue", (parameter.DefaultValue == null) ? "NULL" : parameter.DefaultValue.ToString ());
896 if (direction != "in")
897 AddAttribute (paramNode, "direction", direction);
899 AttributeData.OutputAttributes (document, paramNode, parameter.GetCustomAttributes (false));
904 class AttributeData : BaseData
908 AttributeData (XmlDocument doc, XmlNode parent, object[] attributes)
914 public override void DoOutput ()
916 if (document == null)
917 throw new InvalidOperationException ("Document not set");
919 if (atts == null || atts.Length == 0)
922 XmlNode natts = parent.SelectSingleNode("attributes");
924 natts = document.CreateElement ("attributes", null);
925 parent.AppendChild (natts);
928 for (int i = 0; i < atts.Length; ++i) {
929 Type t = atts [i].GetType ();
930 if (!t.IsPublic && !IsMonoTODOAttribute (t.Name))
933 // we ignore attributes that inherit from SecurityAttribute on purpose as they:
934 // * aren't part of GetCustomAttributes in Fx 1.0/1.1;
935 // * are encoded differently and in a different metadata table; and
936 // * won't ever exactly match MS implementation (from a syntax pov)
937 if (t.IsSubclassOf (typeof (SecurityAttribute)))
940 XmlNode node = document.CreateElement ("attribute");
941 AddAttribute (node, "name", t.ToString ());
943 XmlNode properties = null;
944 foreach (PropertyInfo pi in TypeData.GetProperties (t)) {
945 if (pi.Name == "TypeId")
948 if (properties == null) {
949 properties = node.AppendChild (document.CreateElement ("properties"));
953 object o = pi.GetValue (atts [i], null);
955 XmlNode n = properties.AppendChild (document.CreateElement ("property"));
956 AddAttribute (n, "name", pi.Name);
959 AddAttribute (n, "null", "true");
963 string value = o.ToString ();
964 if (t == typeof (GuidAttribute))
965 value = value.ToUpper ();
967 AddAttribute (n, "value", value);
969 catch (TargetInvocationException) {
974 natts.AppendChild (node);
978 public static void OutputAttributes (XmlDocument doc, XmlNode parent, object[] attributes)
980 AttributeData ad = new AttributeData (doc, parent, attributes);
984 private static bool MustDocumentAttribute (Type attributeType)
986 // only document MonoTODOAttribute and public attributes
987 return attributeType.IsPublic || IsMonoTODOAttribute (attributeType.Name);
993 private Parameters () {}
995 public static string GetSignature (ParameterInfo [] infos)
997 if (infos == null || infos.Length == 0)
1000 StringBuilder sb = new StringBuilder ();
1001 foreach (ParameterInfo info in infos) {
1005 else if (info.IsRetval)
1007 else if (info.IsOut)
1012 string type_name = info.ParameterType.ToString ().Replace ('<', '[').Replace ('>', ']');
1013 sb.AppendFormat ("{0}{1}, ", modifier, type_name);
1016 sb.Length -= 2; // remove ", "
1017 return sb.ToString ();
1022 class TypeComparer : IComparer
1024 public static TypeComparer Default = new TypeComparer ();
1026 public int Compare (object a, object b)
1030 int result = String.Compare (ta.Namespace, tb.Namespace);
1034 return String.Compare (ta.Name, tb.Name);
1038 class MemberInfoComparer : IComparer
1040 public static MemberInfoComparer Default = new MemberInfoComparer ();
1042 public int Compare (object a, object b)
1044 MemberInfo ma = (MemberInfo) a;
1045 MemberInfo mb = (MemberInfo) b;
1046 return String.Compare (ma.Name, mb.Name);
1050 class MethodBaseComparer : IComparer
1052 public static MethodBaseComparer Default = new MethodBaseComparer ();
1054 public int Compare (object a, object b)
1056 MethodBase ma = (MethodBase) a;
1057 MethodBase mb = (MethodBase) b;
1058 int res = String.Compare (ma.Name, mb.Name);
1062 ParameterInfo [] pia = ma.GetParameters ();
1063 ParameterInfo [] pib = mb.GetParameters ();
1064 if (pia.Length != pib.Length)
1065 return pia.Length - pib.Length;
1067 string siga = Parameters.GetSignature (pia);
1068 string sigb = Parameters.GetSignature (pib);
1069 return String.Compare (siga, sigb);