2005-06-29 Jonathan Chambers <jonathan.chambers@ansys.com>
[mcs.git] / tools / corcompare / mono-api-diff.cs
blobb4983c0590e33a298ff653fd44fbced513ee4d9a
1 //
2 // mono-api-diff.cs - Compares 2 xml files produced by mono-api-info and
3 // produces a file suitable to build class status pages.
4 //
5 // Authors:
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // (C) 2003 Novell, Inc (http://www.novell.com)
9 //
11 using System;
12 using System.Collections;
13 using System.IO;
14 using System.Reflection;
15 using System.Text;
16 using System.Xml;
18 namespace Mono.AssemblyCompare
20 class Driver
22 static int Main (string [] args)
24 if (args.Length != 2)
25 return 1;
27 XMLAssembly ms = CreateXMLAssembly (args [0]);
28 XMLAssembly mono = CreateXMLAssembly (args [1]);
29 XmlDocument doc = ms.CompareAndGetDocument (mono);
31 XmlTextWriter writer = new XmlTextWriter (Console.Out);
32 writer.Formatting = Formatting.Indented;
33 doc.WriteTo (writer);
35 return 0;
38 static XMLAssembly CreateXMLAssembly (string file)
40 XmlDocument doc = new XmlDocument ();
41 doc.Load (File.OpenRead (file));
43 XmlNode node = doc.SelectSingleNode ("/assemblies/assembly");
44 XMLAssembly result = new XMLAssembly ();
45 try {
46 result.LoadData (node);
47 } catch (Exception e) {
48 Console.Error.WriteLine ("Error loading {0}: {1}\n{2}", file, e.Message, e);
49 Environment.Exit (1);
52 return result;
56 class Counters
58 public int Present;
59 public int PresentTotal;
60 public int Missing;
61 public int MissingTotal;
62 public int Todo;
63 public int TodoTotal;
65 public int Extra;
66 public int ExtraTotal;
67 public int Warning;
68 public int WarningTotal;
69 public int ErrorTotal;
71 public Counters ()
75 public void AddPartialToPartial (Counters other)
77 Present += other.Present;
78 Extra += other.Extra;
79 Missing += other.Missing;
81 Todo += other.Todo;
82 Warning += other.Warning;
83 AddPartialToTotal (other);
86 public void AddPartialToTotal (Counters other)
88 PresentTotal += other.Present;
89 ExtraTotal += other.Extra;
90 MissingTotal += other.Missing;
92 TodoTotal += other.Todo;
93 WarningTotal += other.Warning;
96 public void AddTotalToPartial (Counters other)
98 Present += other.PresentTotal;
99 Extra += other.ExtraTotal;
100 Missing += other.MissingTotal;
102 Todo += other.TodoTotal;
103 Warning += other.WarningTotal;
104 AddTotalToTotal (other);
107 public void AddTotalToTotal (Counters other)
109 PresentTotal += other.PresentTotal;
110 ExtraTotal += other.ExtraTotal;
111 MissingTotal += other.MissingTotal;
113 TodoTotal += other.TodoTotal;
114 WarningTotal += other.WarningTotal;
115 ErrorTotal += other.ErrorTotal;
118 public int Total {
119 get { return Present + Missing; }
122 public int AbsTotal {
123 get { return PresentTotal + MissingTotal; }
126 public int Ok {
127 get { return Present - Todo; }
130 public int OkTotal {
131 get { return PresentTotal - TodoTotal - ErrorTotal; }
134 public override string ToString ()
136 StringWriter sw = new StringWriter ();
137 sw.WriteLine ("Present: {0}", Present);
138 sw.WriteLine ("PresentTotal: {0}", PresentTotal);
139 sw.WriteLine ("Missing: {0}", Missing);
140 sw.WriteLine ("MissingTotal: {0}", MissingTotal);
141 sw.WriteLine ("Todo: {0}", Todo);
142 sw.WriteLine ("TodoTotal: {0}", TodoTotal);
143 sw.WriteLine ("Extra: {0}", Extra);
144 sw.WriteLine ("ExtraTotal: {0}", ExtraTotal);
145 sw.WriteLine ("Warning: {0}", Warning);
146 sw.WriteLine ("WarningTotal: {0}", WarningTotal);
147 sw.WriteLine ("ErrorTotal: {0}", ErrorTotal);
148 sw.WriteLine ("--");
149 return sw.GetStringBuilder ().ToString ();
153 abstract class XMLData
155 protected XmlDocument document;
156 protected Counters counters;
157 bool haveWarnings;
159 public XMLData ()
161 counters = new Counters ();
164 public virtual void LoadData (XmlNode node)
168 protected object [] LoadRecursive (XmlNodeList nodeList, Type type)
170 ArrayList list = new ArrayList ();
171 foreach (XmlNode node in nodeList) {
172 XMLData data = (XMLData) Activator.CreateInstance (type);
173 data.LoadData (node);
174 list.Add (data);
177 return (object []) list.ToArray (type);
180 protected void AddAttribute (XmlNode node, string name, string value)
182 XmlAttribute attr = document.CreateAttribute (name);
183 attr.Value = value;
184 node.Attributes.Append (attr);
187 protected void AddExtra (XmlNode node)
189 //TODO: count all the subnodes?
190 AddAttribute (node, "presence", "extra");
191 AddAttribute (node, "ok", "1");
192 AddAttribute (node, "ok_total", "1");
193 AddAttribute (node, "extra", "1");
194 AddAttribute (node, "extra_total", "1");
197 public void AddCountersAttributes (XmlNode node)
199 if (counters.Missing > 0)
200 AddAttribute (node, "missing", counters.Missing.ToString ());
202 if (counters.Present > 0)
203 AddAttribute (node, "present", counters.Present.ToString ());
205 if (counters.Extra > 0)
206 AddAttribute (node, "extra", counters.Extra.ToString ());
208 if (counters.Ok > 0)
209 AddAttribute (node, "ok", counters.Ok.ToString ());
211 if (counters.Total > 0) {
212 int percent = (100 * counters.Ok / counters.Total);
213 AddAttribute (node, "complete", percent.ToString ());
216 if (counters.Todo > 0)
217 AddAttribute (node, "todo", counters.Todo.ToString ());
219 if (counters.Warning > 0)
220 AddAttribute (node, "warning", counters.Warning.ToString ());
222 if (counters.MissingTotal > 0)
223 AddAttribute (node, "missing_total", counters.MissingTotal.ToString ());
225 if (counters.PresentTotal > 0)
226 AddAttribute (node, "present_total", counters.PresentTotal.ToString ());
228 if (counters.ExtraTotal > 0)
229 AddAttribute (node, "extra_total", counters.ExtraTotal.ToString ());
231 if (counters.OkTotal > 0)
232 AddAttribute (node, "ok_total", counters.OkTotal.ToString ());
234 if (counters.AbsTotal > 0) {
235 int percent = (100 * counters.OkTotal / counters.AbsTotal);
236 AddAttribute (node, "complete_total", percent.ToString ());
239 if (counters.TodoTotal > 0) {
240 AddAttribute (node, "todo_total", counters.TodoTotal.ToString ());
241 //TODO: should be different on error. check error cases in corcompare.
242 AddAttribute (node, "error_total", counters.Todo.ToString ());
245 if (counters.WarningTotal > 0)
246 AddAttribute (node, "warning_total", counters.WarningTotal.ToString ());
250 protected void AddWarning (XmlNode parent, string fmt, params object [] args)
252 counters.Warning++;
253 haveWarnings = true;
254 XmlNode warnings = parent.SelectSingleNode ("warnings");
255 if (warnings == null) {
256 warnings = document.CreateElement ("warnings", null);
257 parent.AppendChild (warnings);
260 AddAttribute (parent, "error", "warning");
261 XmlNode warning = document.CreateElement ("warning", null);
262 AddAttribute (warning, "text", String.Format (fmt, args));
263 warnings.AppendChild (warning);
266 public bool HaveWarnings {
267 get { return haveWarnings; }
270 public Counters Counters {
271 get { return counters; }
274 public abstract void CompareTo (XmlDocument doc, XmlNode parent, object other);
277 abstract class XMLNameGroup : XMLData
279 protected XmlNode group;
280 protected Hashtable keys;
282 public override void LoadData (XmlNode node)
284 if (node == null)
285 throw new ArgumentNullException ("node");
287 if (node.Name != GroupName)
288 throw new FormatException (String.Format ("Expecting <{0}>", GroupName));
290 keys = new Hashtable ();
291 foreach (XmlNode n in node.ChildNodes) {
292 string name = n.Attributes ["name"].Value;
293 if (CheckIfAdd (name, n)) {
294 string key = GetNodeKey (name, n);
295 //keys.Add (key, name);
296 keys [key] = name;
297 LoadExtraData (key, n);
302 protected virtual bool CheckIfAdd (string value, XmlNode node)
304 return true;
307 protected virtual void LoadExtraData (string name, XmlNode node)
311 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
313 this.document = doc;
314 if (group == null)
315 group = doc.CreateElement (GroupName, null);
317 Hashtable okeys = null;
318 if (other != null && ((XMLNameGroup) other).keys != null) {
319 okeys = ((XMLNameGroup) other).keys;
322 XmlNode node = null;
323 bool onull = (okeys == null);
324 if (keys != null) {
325 foreach (DictionaryEntry entry in keys) {
326 node = doc.CreateElement (Name, null);
327 group.AppendChild (node);
328 string key = (string) entry.Key;
329 string name = (string) entry.Value;
330 AddAttribute (node, "name", name);
332 if (!onull && HasKey (key, okeys)) {
333 CompareToInner (key, node, (XMLNameGroup) other);
334 okeys.Remove (key);
335 counters.Present++;
336 } else {
337 AddAttribute (node, "presence", "missing");
338 counters.Missing++;
343 if (!onull && okeys.Count != 0) {
344 foreach (string value in okeys.Values) {
345 node = doc.CreateElement (Name, null);
346 AddAttribute (node, "name", (string) value);
347 AddAttribute (node, "presence", "extra");
348 group.AppendChild (node);
349 counters.Extra++;
353 if (group.HasChildNodes)
354 parent.AppendChild (group);
357 protected virtual void CompareToInner (string name, XmlNode node, XMLNameGroup other)
361 public virtual string GetNodeKey (string name, XmlNode node)
363 return name;
366 public virtual bool HasKey (string key, Hashtable other)
368 return other.ContainsKey (key);
371 public abstract string GroupName { get; }
372 public abstract string Name { get; }
375 class XMLAssembly : XMLData
377 XMLAttributes attributes;
378 XMLNamespace [] namespaces;
379 string name;
380 string version;
382 public override void LoadData (XmlNode node)
384 if (node == null)
385 throw new ArgumentNullException ("node");
387 name = node.Attributes ["name"].Value;
388 version = node.Attributes ["version"].Value;
389 XmlNode atts = node.FirstChild;
390 attributes = new XMLAttributes ();
391 if (atts.Name == "attributes") {
392 attributes.LoadData (atts);
393 atts = atts.NextSibling;
396 if (atts == null || atts.Name != "namespaces") {
397 Console.Error.WriteLine ("Warning: no namespaces found!");
398 return;
401 namespaces = (XMLNamespace []) LoadRecursive (atts.ChildNodes, typeof (XMLNamespace));
404 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
406 XMLAssembly assembly = (XMLAssembly) other;
408 XmlNode childA = doc.CreateElement ("assembly", null);
409 AddAttribute (childA, "name", name);
410 AddAttribute (childA, "version", version);
411 if (name != assembly.name)
412 AddWarning (childA, "Assembly names not equal: {0}, {1}", name, assembly.name);
414 if (version != assembly.version)
415 AddWarning (childA, "Assembly version not equal: {0}, {1}", version, assembly.version);
417 parent.AppendChild (childA);
419 attributes.CompareTo (doc, childA, assembly.attributes);
420 counters.AddPartialToPartial (attributes.Counters);
422 CompareNamespaces (childA, assembly.namespaces);
423 if (assembly.attributes != null && assembly.attributes.IsTodo) {
424 counters.Todo++;
425 counters.TodoTotal++;
426 counters.ErrorTotal++;
427 AddAttribute (childA, "error", "todo");
428 if (assembly.attributes.Comment != null)
429 AddAttribute (childA, "comment", assembly.attributes.Comment);
432 AddCountersAttributes (childA);
435 void CompareNamespaces (XmlNode parent, XMLNamespace [] other)
437 ArrayList newNS = new ArrayList ();
438 XmlNode group = document.CreateElement ("namespaces", null);
439 parent.AppendChild (group);
441 Hashtable oh = CreateHash (other);
442 XmlNode node = null;
443 int count = (namespaces == null) ? 0 : namespaces.Length;
444 for (int i = 0; i < count; i++) {
445 XMLNamespace xns = namespaces [i];
447 node = document.CreateElement ("namespace", null);
448 newNS.Add (node);
449 AddAttribute (node, "name", xns.Name);
451 if (oh.ContainsKey (xns.Name)) {
452 int idx = (int) oh [xns.Name];
453 xns.CompareTo (document, node, other [idx]);
454 other [idx] = null;
455 xns.AddCountersAttributes (node);
456 counters.Present++;
457 counters.PresentTotal++;
458 counters.AddPartialToTotal (xns.Counters);
459 } else {
460 AddAttribute (node, "presence", "missing");
461 counters.Missing++;
462 counters.MissingTotal++;
466 if (other != null) {
467 count = other.Length;
468 for (int i = 0; i < count; i++) {
469 XMLNamespace n = other [i];
470 if (n == null)
471 continue;
473 node = document.CreateElement ("namespace", null);
474 newNS.Add (node);
475 AddAttribute (node, "name", n.Name);
476 AddExtra (node);
477 counters.ExtraTotal++;
481 XmlNode [] nodes = (XmlNode []) newNS.ToArray (typeof (XmlNode));
482 Array.Sort (nodes, XmlNodeComparer.Default);
483 foreach (XmlNode nn in nodes)
484 group.AppendChild (nn);
487 static Hashtable CreateHash (XMLNamespace [] other)
489 Hashtable result = new Hashtable ();
490 if (other != null) {
491 int i = 0;
492 foreach (XMLNamespace n in other) {
493 result [n.Name] = i++;
497 return result;
500 public XmlDocument CompareAndGetDocument (XMLAssembly other)
502 XmlDocument doc = new XmlDocument ();
503 this.document = doc;
504 XmlNode parent = doc.CreateElement ("assemblies", null);
505 doc.AppendChild (parent);
507 CompareTo (doc, parent, other);
509 XmlNode decl = doc.CreateXmlDeclaration ("1.0", null, null);
510 doc.InsertBefore (decl, doc.DocumentElement);
512 return doc;
516 class XMLNamespace : XMLData
518 string name;
519 XMLClass [] types;
521 public override void LoadData (XmlNode node)
523 if (node == null)
524 throw new ArgumentNullException ("node");
526 if (node.Name != "namespace")
527 throw new FormatException ("Expecting <namespace>");
529 name = node.Attributes ["name"].Value;
530 XmlNode classes = node.FirstChild;
531 if (classes == null) {
532 Console.Error.WriteLine ("Warning: no classes for {0}", node.Attributes ["name"]);
533 return;
536 if (classes.Name != "classes")
537 throw new FormatException ("Expecting <classes>. Got <" + classes.Name + ">");
539 types = (XMLClass []) LoadRecursive (classes.ChildNodes, typeof (XMLClass));
542 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
544 this.document = doc;
545 XMLNamespace nspace = (XMLNamespace) other;
547 XmlNode childA = doc.CreateElement ("classes", null);
548 parent.AppendChild (childA);
550 CompareTypes (childA, nspace.types);
553 void CompareTypes (XmlNode parent, XMLClass [] other)
555 ArrayList newNodes = new ArrayList ();
556 Hashtable oh = CreateHash (other);
557 XmlNode node = null;
558 int count = (types == null) ? 0 : types.Length;
559 for (int i = 0; i < count; i++) {
560 XMLClass xclass = types [i];
562 node = document.CreateElement ("class", null);
563 newNodes.Add (node);
564 AddAttribute (node, "name", xclass.Name);
565 AddAttribute (node, "type", xclass.Type);
567 if (oh.ContainsKey (xclass.Name)) {
568 int idx = (int) oh [xclass.Name];
569 xclass.CompareTo (document, node, other [idx]);
570 other [idx] = null;
571 counters.AddPartialToPartial (xclass.Counters);
572 } else {
573 AddAttribute (node, "presence", "missing");
574 counters.Missing++;
575 counters.MissingTotal++;
579 if (other != null) {
580 count = other.Length;
581 for (int i = 0; i < count; i++) {
582 XMLClass c = other [i];
583 if (c == null || c.Name.EndsWith ("TODOAttribute"))
584 continue;
586 node = document.CreateElement ("class", null);
587 newNodes.Add (node);
588 AddAttribute (node, "name", c.Name);
589 AddAttribute (node, "type", c.Type);
590 AddExtra (node);
591 counters.Extra++;
592 counters.ExtraTotal++;
596 XmlNode [] nodes = (XmlNode []) newNodes.ToArray (typeof (XmlNode));
597 Array.Sort (nodes, XmlNodeComparer.Default);
598 foreach (XmlNode nn in nodes)
599 parent.AppendChild (nn);
602 static Hashtable CreateHash (XMLClass [] other)
604 Hashtable result = new Hashtable ();
605 if (other != null) {
606 int i = 0;
607 foreach (XMLClass c in other) {
608 result [c.Name] = i++;
612 return result;
615 public string Name {
616 get { return name; }
620 class XMLClass : XMLData
622 string name;
623 string type;
624 string baseName;
625 bool isSealed;
626 bool isSerializable;
627 bool isAbstract;
628 string charSet;
629 string layout;
630 XMLAttributes attributes;
631 XMLInterfaces interfaces;
632 XMLGenericTypeConstraints genericConstraints;
633 XMLFields fields;
634 XMLConstructors constructors;
635 XMLProperties properties;
636 XMLEvents events;
637 XMLMethods methods;
638 XMLClass [] nested;
640 public override void LoadData (XmlNode node)
642 if (node == null)
643 throw new ArgumentNullException ("node");
645 name = node.Attributes ["name"].Value;
646 type = node.Attributes ["type"].Value;
647 XmlAttribute xatt = node.Attributes ["base"];
648 if (xatt != null)
649 baseName = xatt.Value;
651 xatt = node.Attributes ["sealed"];
652 isSealed = (xatt != null && xatt.Value == "true");
654 xatt = node.Attributes ["abstract"];
655 isAbstract = (xatt != null && xatt.Value == "true");
657 xatt = node.Attributes["serializable"];
658 isSerializable = (xatt != null && xatt.Value == "true");
660 xatt = node.Attributes["charset"];
661 if (xatt != null)
662 charSet = xatt.Value;
664 xatt = node.Attributes["layout"];
665 if (xatt != null)
666 layout = xatt.Value;
668 XmlNode child = node.FirstChild;
669 if (child == null) {
670 // Console.Error.WriteLine ("Empty class {0} {1}", name, type);
671 return;
674 if (child.Name == "attributes") {
675 attributes = new XMLAttributes ();
676 attributes.LoadData (child);
677 child = child.NextSibling;
680 if (child != null && child.Name == "interfaces") {
681 interfaces = new XMLInterfaces ();
682 interfaces.LoadData (child);
683 child = child.NextSibling;
686 if (child != null && child.Name == "generic-type-constraints") {
687 genericConstraints = new XMLGenericTypeConstraints ();
688 genericConstraints.LoadData (child);
689 child = child.NextSibling;
692 if (child != null && child.Name == "fields") {
693 fields = new XMLFields ();
694 fields.LoadData (child);
695 child = child.NextSibling;
698 if (child != null && child.Name == "constructors") {
699 constructors = new XMLConstructors ();
700 constructors.LoadData (child);
701 child = child.NextSibling;
704 if (child != null && child.Name == "properties") {
705 properties = new XMLProperties ();
706 properties.LoadData (child);
707 child = child.NextSibling;
710 if (child != null && child.Name == "events") {
711 events = new XMLEvents ();
712 events.LoadData (child);
713 child = child.NextSibling;
716 if (child != null && child.Name == "methods") {
717 methods = new XMLMethods ();
718 methods.LoadData (child);
719 child = child.NextSibling;
722 if (child == null)
723 return;
725 if (child.Name != "classes") {
726 Console.WriteLine ("name: {0} type: {1} {2}", name, type, child.NodeType);
727 throw new FormatException ("Expecting <classes>. Got <" + child.Name + ">");
730 nested = (XMLClass []) LoadRecursive (child.ChildNodes, typeof (XMLClass));
733 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
735 this.document = doc;
736 XMLClass oclass = (XMLClass) other;
738 if (attributes != null || oclass.attributes != null) {
739 if (attributes == null)
740 attributes = new XMLAttributes ();
742 attributes.CompareTo (doc, parent, oclass.attributes);
743 counters.AddPartialToPartial (attributes.Counters);
744 if (oclass.attributes != null && oclass.attributes.IsTodo) {
745 counters.Todo++;
746 counters.TodoTotal++;
747 counters.ErrorTotal++;
748 AddAttribute (parent, "error", "todo");
749 if (oclass.attributes.Comment != null)
750 AddAttribute (parent, "comment", oclass.attributes.Comment);
754 if (type != oclass.type)
755 AddWarning (parent, "Class type is wrong: {0} != {1}", type, oclass.type);
757 if (baseName != oclass.baseName)
758 AddWarning (parent, "Base class is wrong: {0} != {1}", baseName, oclass.baseName);
760 if (isAbstract != oclass.isAbstract || isSealed != oclass.isSealed) {
761 if ((isAbstract && isSealed) || (oclass.isAbstract && oclass.isSealed))
762 AddWarning (parent, "Should {0}be static", (isAbstract && isSealed) ? "" : "not ");
763 else if (isAbstract != oclass.isAbstract)
764 AddWarning (parent, "Should {0}be abstract", isAbstract ? "" : "not ");
765 else if (isSealed != oclass.isSealed)
766 AddWarning (parent, "Should {0}be sealed", isSealed ? "" : "not ");
769 if (isSerializable != oclass.isSerializable)
770 AddWarning (parent, "Should {0}be serializable", isSerializable ? "" : "not ");
772 if (charSet != oclass.charSet)
773 AddWarning (parent, "CharSet is wrong: {0} != {1}", charSet, oclass.charSet);
775 if (layout != oclass.layout)
776 AddWarning (parent, "Layout is wrong: {0} != {1}", layout, oclass.layout);
778 if (interfaces != null || oclass.interfaces != null) {
779 if (interfaces == null)
780 interfaces = new XMLInterfaces ();
782 interfaces.CompareTo (doc, parent, oclass.interfaces);
783 counters.AddPartialToPartial (interfaces.Counters);
786 if (genericConstraints != null || oclass.genericConstraints != null) {
787 if (genericConstraints == null)
788 genericConstraints = new XMLGenericTypeConstraints ();
790 genericConstraints.CompareTo (doc, parent, oclass.genericConstraints);
791 counters.AddPartialToPartial (genericConstraints.Counters);
794 if (fields != null || oclass.fields != null) {
795 if (fields == null)
796 fields = new XMLFields ();
798 fields.CompareTo (doc, parent, oclass.fields);
799 counters.AddPartialToPartial (fields.Counters);
802 if (constructors != null || oclass.constructors != null) {
803 if (constructors == null)
804 constructors = new XMLConstructors ();
806 constructors.CompareTo (doc, parent, oclass.constructors);
807 counters.AddPartialToPartial (constructors.Counters);
810 if (properties != null || oclass.properties != null) {
811 if (properties == null)
812 properties = new XMLProperties ();
814 properties.CompareTo (doc, parent, oclass.properties);
815 counters.AddPartialToPartial (properties.Counters);
818 if (events != null || oclass.events != null) {
819 if (events == null)
820 events = new XMLEvents ();
822 events.CompareTo (doc, parent, oclass.events);
823 counters.AddPartialToPartial (events.Counters);
826 if (methods != null || oclass.methods != null) {
827 if (methods == null)
828 methods = new XMLMethods ();
830 methods.CompareTo (doc, parent, oclass.methods);
831 counters.AddPartialToPartial (methods.Counters);
834 if (nested != null || oclass.nested != null) {
835 XmlNode n = doc.CreateElement ("classes", null);
836 parent.AppendChild (n);
837 CompareTypes (n, oclass.nested);
840 AddCountersAttributes (parent);
843 void CompareTypes (XmlNode parent, XMLClass [] other)
845 ArrayList newNodes = new ArrayList ();
846 Hashtable oh = CreateHash (other);
847 XmlNode node = null;
848 int count = (nested == null) ? 0 : nested.Length;
849 for (int i = 0; i < count; i++) {
850 XMLClass xclass = nested [i];
852 node = document.CreateElement ("nestedclass", null);
853 newNodes.Add (node);
854 AddAttribute (node, "name", xclass.Name);
855 AddAttribute (node, "type", xclass.Type);
857 if (oh.ContainsKey (xclass.Name)) {
858 int idx = (int) oh [xclass.Name];
859 xclass.CompareTo (document, node, other [idx]);
860 other [idx] = null;
861 counters.AddPartialToPartial (xclass.Counters);
862 } else {
863 // TODO: Should I count here?
864 AddAttribute (node, "presence", "missing");
865 counters.Missing++;
866 counters.MissingTotal++;
870 if (other != null) {
871 count = other.Length;
872 for (int i = 0; i < count; i++) {
873 XMLClass c = other [i];
874 if (c == null || c.Name.EndsWith ("TODOAttribute"))
875 continue;
877 node = document.CreateElement ("nestedclass", null);
878 newNodes.Add (node);
879 AddAttribute (node, "name", c.Name);
880 AddExtra (node);
881 counters.Extra++;
882 counters.ExtraTotal++;
886 XmlNode [] nodes = (XmlNode []) newNodes.ToArray (typeof (XmlNode));
887 Array.Sort (nodes, XmlNodeComparer.Default);
888 foreach (XmlNode nn in nodes)
889 parent.AppendChild (nn);
892 static Hashtable CreateHash (XMLClass [] other)
894 Hashtable result = new Hashtable ();
895 if (other != null) {
896 int i = 0;
897 foreach (XMLClass c in other) {
898 result [c.Name] = i++;
902 return result;
905 public string Name {
906 get { return name; }
909 public string Type {
910 get { return type; }
914 class XMLParameter : XMLData
916 string name;
917 string type;
918 string attrib;
919 string direction;
920 bool isUnsafe;
921 bool isOptional;
922 string defaultValue;
924 public override void LoadData (XmlNode node)
926 if (node == null)
927 throw new ArgumentNullException ("node");
929 if (node.Name != "parameter")
930 throw new ArgumentException ("Expecting <parameter>");
932 name = node.Attributes["name"].Value;
933 type = node.Attributes["type"].Value;
934 attrib = node.Attributes["attrib"].Value;
935 if (node.Attributes ["direction"] != null)
936 direction = node.Attributes["direction"].Value;
937 if (node.Attributes["unsafe"] != null)
938 isUnsafe = bool.Parse (node.Attributes["unsafe"].Value);
939 if (node.Attributes["optional"] != null)
940 isOptional = bool.Parse (node.Attributes["optional"].Value);
941 if (node.Attributes["defaultValue"] != null)
942 defaultValue = node.Attributes["defaultValue"].Value;
945 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
947 this.document = doc;
949 XMLParameter oparm = (XMLParameter) other;
951 if (type != oparm.type)
952 AddWarning (parent, "Parameter type is wrong: {0} != {1}", type, oparm.type);
954 if (attrib != oparm.attrib)
955 AddWarning (parent, "Parameter attributes wrong: {0} != {1}", attrib, oparm.attrib);
957 if (direction != oparm.direction)
958 AddWarning (parent, "Parameter direction wrong: {0} != {1}", direction, oparm.direction);
960 if (isUnsafe != oparm.isUnsafe)
961 AddWarning (parent, "Parameter unsafe wrong: {0} != {1}", isUnsafe, oparm.isUnsafe);
963 if (isOptional != oparm.isOptional)
964 AddWarning (parent, "Parameter optional wrong: {0} != {1}", isOptional, oparm.isOptional);
966 if (defaultValue != oparm.defaultValue)
967 AddWarning (parent, "Parameter default value wrong: {0} != {1}", (defaultValue == null) ? "(no default value)" : defaultValue, (oparm.defaultValue == null) ? "(no default value)" : oparm.defaultValue);
970 public string Name {
971 get { return name; }
975 class XMLAttributeProperties: XMLNameGroup
977 static Hashtable ignored_properties;
978 static XMLAttributeProperties ()
980 ignored_properties = new Hashtable ();
981 ignored_properties.Add ("System.Reflection.AssemblyKeyFileAttribute", "KeyFile");
982 ignored_properties.Add ("System.Reflection.AssemblyCompanyAttribute", "Company");
983 ignored_properties.Add ("System.Reflection.AssemblyConfigurationAttribute", "Configuration");
984 ignored_properties.Add ("System.Reflection.AssemblyCopyrightAttribute", "Copyright");
985 ignored_properties.Add ("System.Reflection.AssemblyProductAttribute", "Product");
986 ignored_properties.Add ("System.Reflection.AssemblyTrademarkAttribute", "Trademark");
987 ignored_properties.Add ("System.Reflection.AssemblyInformationalVersionAttribute", "InformationalVersion");
989 ignored_properties.Add ("System.ObsoleteAttribute", "Message");
990 ignored_properties.Add ("System.IO.IODescriptionAttribute", "Description");
991 ignored_properties.Add ("System.Diagnostics.MonitoringDescriptionAttribute", "Description");
994 Hashtable properties = new Hashtable ();
995 string attribute;
997 public XMLAttributeProperties (string attribute)
999 this.attribute = attribute;
1002 public override void LoadData(XmlNode node)
1004 if (node == null)
1005 throw new ArgumentNullException ("node");
1007 if (node.ChildNodes == null)
1008 return;
1010 string ignored = ignored_properties [attribute] as string;
1012 foreach (XmlNode n in node.ChildNodes) {
1013 string name = n.Attributes ["name"].Value;
1014 if (ignored == name)
1015 continue;
1017 if (n.Attributes ["null"] != null) {
1018 properties.Add (name, null);
1019 continue;
1021 string value = n.Attributes ["value"].Value;
1022 properties.Add (name, value);
1026 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
1028 this.document = doc;
1030 Hashtable other_properties = ((XMLAttributeProperties)other).properties;
1031 foreach (DictionaryEntry de in other_properties) {
1032 object other_value = properties [de.Key];
1034 if (de.Value == null) {
1035 if (other_value != null)
1036 AddWarning (parent, "Property '{0}' is 'null' and should be '{1}'", de.Key, other_value);
1037 continue;
1040 if (de.Value.Equals (other_value))
1041 continue;
1043 AddWarning (parent, "Property '{0}' is '{1}' and should be '{2}'",
1044 de.Key, de.Value, other_value == null ? "null" : other_value);
1048 public override string GroupName {
1049 get {
1050 return "properties";
1054 public override string Name {
1055 get {
1056 return "";
1061 class XMLAttributes : XMLNameGroup
1063 Hashtable properties = new Hashtable ();
1065 bool isTodo;
1066 string comment;
1068 protected override bool CheckIfAdd (string value, XmlNode node)
1070 if (value.EndsWith ("TODOAttribute")) {
1071 isTodo = true;
1073 XmlNode pNode = node.SelectSingleNode ("properties");
1074 if (pNode.ChildNodes [0].Attributes ["value"] != null) {
1075 comment = pNode.ChildNodes [0].Attributes ["value"].Value;
1077 return false;
1080 return true;
1083 protected override void CompareToInner (string name, XmlNode node, XMLNameGroup other)
1085 XMLAttributeProperties other_prop = ((XMLAttributes)other).properties [name] as XMLAttributeProperties;
1086 XMLAttributeProperties this_prop = properties [name] as XMLAttributeProperties;
1087 if (other_prop == null || this_prop == null)
1088 return;
1090 this_prop.CompareTo (document, node, other_prop);
1091 counters.AddPartialToPartial (this_prop.Counters);
1094 public override string GetNodeKey (string name, XmlNode node)
1096 string key = null;
1098 // if multiple attributes with the same name (type) exist, then we
1099 // cannot be sure which attributes correspond, so we must use the
1100 // name of the attribute (type) and the name/value of its properties
1101 // as key
1103 XmlNodeList attributes = node.ParentNode.SelectNodes("attribute[@name='" + name + "']");
1104 if (attributes.Count > 1) {
1105 ArrayList keyParts = new ArrayList ();
1107 XmlNodeList properties = node.SelectNodes ("properties/property");
1108 foreach (XmlNode property in properties) {
1109 XmlAttributeCollection attrs = property.Attributes;
1110 if (attrs["value"] != null) {
1111 keyParts.Add (attrs["name"].Value + "=" + attrs["value"].Value);
1112 } else {
1113 keyParts.Add (attrs["name"].Value + "=");
1117 // sort properties by name, as order of properties in XML is
1118 // undefined
1119 keyParts.Sort ();
1121 // insert name (type) of attribute
1122 keyParts.Insert (0, name);
1124 StringBuilder sb = new StringBuilder ();
1125 foreach (string value in keyParts) {
1126 sb.Append (value);
1127 sb.Append (';');
1129 key = sb.ToString ();
1130 } else {
1131 key = name;
1134 return key;
1137 protected override void LoadExtraData(string name, XmlNode node)
1139 XmlNode pNode = node.SelectSingleNode ("properties");
1141 if (name.EndsWith ("TODOAttribute")) {
1142 isTodo = true;
1143 if (pNode.ChildNodes [0].Attributes ["value"] != null) {
1144 comment = pNode.ChildNodes [0].Attributes ["value"].Value;
1146 return;
1149 if (pNode != null) {
1150 XMLAttributeProperties p = new XMLAttributeProperties (name);
1151 p.LoadData (pNode);
1153 properties[name] = p;
1157 public override string GroupName {
1158 get { return "attributes"; }
1161 public override string Name {
1162 get { return "attribute"; }
1165 public bool IsTodo {
1166 get { return isTodo; }
1169 public string Comment {
1170 get { return comment; }
1174 class XMLInterfaces : XMLNameGroup
1176 public override string GroupName {
1177 get { return "interfaces"; }
1180 public override string Name {
1181 get { return "interface"; }
1185 abstract class XMLGenericGroup : XMLNameGroup
1187 string attributes;
1189 protected override void LoadExtraData (string name, XmlNode node)
1191 attributes = ((XmlElement) node).GetAttribute ("generic-attribute");
1194 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1196 base.CompareToInner (name, parent, other);
1198 XMLGenericGroup g = (XMLGenericGroup) other;
1199 if (attributes != g.attributes)
1200 AddWarning (parent, "Incorrect generic attributes: '{0}' != '{1}'", attributes, g.attributes);
1204 class XMLGenericTypeConstraints : XMLGenericGroup
1206 public override string GroupName {
1207 get { return "generic-type-constraints"; }
1210 public override string Name {
1211 get { return "generic-type-constraint"; }
1215 class XMLGenericMethodConstraints : XMLGenericGroup
1217 public override string GroupName {
1218 get { return "generic-method-constraints"; }
1221 public override string Name {
1222 get { return "generic-method-constraint"; }
1226 abstract class XMLMember : XMLNameGroup
1228 Hashtable attributeMap;
1229 Hashtable access = new Hashtable ();
1231 protected override void LoadExtraData (string name, XmlNode node)
1233 XmlAttribute xatt = node.Attributes ["attrib"];
1234 if (xatt != null)
1235 access [name] = xatt.Value;
1237 XmlNode orig = node;
1239 node = node.FirstChild;
1240 while (node != null) {
1241 if (node != null && node.Name == "attributes") {
1242 XMLAttributes a = new XMLAttributes ();
1243 a.LoadData (node);
1244 if (attributeMap == null)
1245 attributeMap = new Hashtable ();
1247 attributeMap [name] = a;
1248 break;
1250 node = node.NextSibling;
1253 base.LoadExtraData (name, orig);
1256 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1258 base.CompareToInner (name, parent, other);
1259 XMLMember mb = other as XMLMember;
1260 XMLAttributes att = null;
1261 XMLAttributes oatt = null;
1262 if (attributeMap != null)
1263 att = attributeMap [name] as XMLAttributes;
1265 if (mb != null && mb.attributeMap != null)
1266 oatt = mb.attributeMap [name] as XMLAttributes;
1268 if (att != null || oatt != null) {
1269 if (att == null)
1270 att = new XMLAttributes ();
1272 att.CompareTo (document, parent, oatt);
1273 counters.AddPartialToPartial(att.Counters);
1274 if (oatt != null && oatt.IsTodo) {
1275 counters.Todo++;
1276 counters.ErrorTotal++;
1277 AddAttribute (parent, "error", "todo");
1278 if (oatt.Comment != null)
1279 AddAttribute (parent, "comment", oatt.Comment);
1283 XMLMember member = (XMLMember) other;
1284 string acc = access [name] as string;
1285 if (acc == null)
1286 return;
1288 string oacc = null;
1289 if (member.access != null)
1290 oacc = member.access [name] as string;
1292 string accName = ConvertToString (Int32.Parse (acc));
1293 string oaccName = "";
1294 if (oacc != null)
1295 oaccName = ConvertToString (Int32.Parse (oacc));
1297 if (accName != oaccName)
1298 AddWarning (parent, "Incorrect attributes: '{0}' != '{1}'", accName, oaccName);
1301 protected virtual string ConvertToString (int att)
1303 return null;
1307 class XMLFields : XMLMember
1309 Hashtable fieldTypes;
1310 Hashtable fieldValues;
1312 protected override void LoadExtraData (string name, XmlNode node)
1314 XmlAttribute xatt = node.Attributes ["fieldtype"];
1315 if (xatt != null) {
1316 if (fieldTypes == null)
1317 fieldTypes = new Hashtable ();
1319 fieldTypes [name] = xatt.Value;
1322 xatt = node.Attributes ["value"];
1323 if (xatt != null) {
1324 if (fieldValues == null)
1325 fieldValues = new Hashtable ();
1327 fieldValues[name] = xatt.Value;
1330 base.LoadExtraData (name, node);
1333 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1335 base.CompareToInner (name, parent, other);
1336 XMLFields fields = (XMLFields) other;
1337 if (fieldTypes != null) {
1338 string ftype = fieldTypes [name] as string;
1339 string oftype = null;
1340 if (fields.fieldTypes != null)
1341 oftype = fields.fieldTypes [name] as string;
1343 if (ftype != oftype)
1344 AddWarning (parent, "Field type is {0} and should be {1}", oftype, ftype);
1346 if (fieldValues != null) {
1347 string fvalue = fieldValues [name] as string;
1348 string ofvalue = null;
1349 if (fields.fieldValues != null)
1350 ofvalue = fields.fieldValues [name] as string;
1352 if (fvalue != ofvalue)
1353 AddWarning (parent, "Field value is {0} and should be {1}", ofvalue, fvalue);
1357 protected override string ConvertToString (int att)
1359 FieldAttributes fa = (FieldAttributes) att;
1360 return fa.ToString ();
1363 public override string GroupName {
1364 get { return "fields"; }
1367 public override string Name {
1368 get { return "field"; }
1372 class XMLParameters : XMLNameGroup
1374 public override void LoadData (XmlNode node)
1376 if (node == null)
1377 throw new ArgumentNullException ("node");
1379 if (node.Name != GroupName)
1380 throw new FormatException (String.Format ("Expecting <{0}>", GroupName));
1382 keys = new Hashtable ();
1383 foreach (XmlNode n in node.ChildNodes) {
1384 string name = n.Attributes["name"].Value;
1385 string key = GetNodeKey (name, n);
1386 XMLParameter parm = new XMLParameter ();
1387 parm.LoadData (n);
1388 keys.Add (key, parm);
1389 LoadExtraData (key, n);
1393 public override string GroupName {
1394 get {
1395 return "parameters";
1399 public override string Name {
1400 get {
1401 return "parameter";
1405 public override string GetNodeKey (string name, XmlNode node)
1407 return node.Attributes["position"].Value;
1410 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
1412 this.document = doc;
1413 if (group == null)
1414 group = doc.CreateElement (GroupName, null);
1416 Hashtable okeys = null;
1417 if (other != null && ((XMLParameters) other).keys != null) {
1418 okeys = ((XMLParameters) other).keys;
1421 XmlNode node = null;
1422 bool onull = (okeys == null);
1423 if (keys != null) {
1424 foreach (DictionaryEntry entry in keys) {
1425 node = doc.CreateElement (Name, null);
1426 group.AppendChild (node);
1427 string key = (string) entry.Key;
1428 XMLParameter parm = (XMLParameter) entry.Value;
1429 AddAttribute (node, "name", parm.Name);
1431 if (!onull && HasKey (key, okeys)) {
1432 parm.CompareTo (document, node, okeys[key]);
1433 counters.AddPartialToPartial (parm.Counters);
1434 okeys.Remove (key);
1435 counters.Present++;
1436 } else {
1437 AddAttribute (node, "presence", "missing");
1438 counters.Missing++;
1443 if (!onull && okeys.Count != 0) {
1444 foreach (XMLParameter value in okeys.Values) {
1445 node = doc.CreateElement (Name, null);
1446 AddAttribute (node, "name", value.Name);
1447 AddAttribute (node, "presence", "extra");
1448 group.AppendChild (node);
1449 counters.Extra++;
1453 if (group.HasChildNodes)
1454 parent.AppendChild (group);
1458 class XMLProperties : XMLMember
1460 Hashtable nameToMethod = new Hashtable ();
1462 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1464 Counters copy = counters;
1465 counters = new Counters();
1467 XMLProperties oprop = other as XMLProperties;
1468 if (oprop != null) {
1469 XMLMethods m = nameToMethod [name] as XMLMethods;
1470 XMLMethods om = oprop.nameToMethod [name] as XMLMethods;
1471 if (m != null || om != null) {
1472 if (m == null)
1473 m = new XMLMethods ();
1475 m.CompareTo(document, parent, om);
1476 counters.AddPartialToPartial(m.Counters);
1480 base.CompareToInner (name, parent, other);
1481 AddCountersAttributes(parent);
1483 copy.AddPartialToPartial(counters);
1484 counters = copy;
1487 protected override void LoadExtraData (string name, XmlNode node)
1489 XmlNode orig = node;
1490 node = node.FirstChild;
1491 while (node != null) {
1492 if (node != null && node.Name == "methods") {
1493 XMLMethods m = new XMLMethods ();
1494 XmlNode parent = node.ParentNode;
1495 string key = GetNodeKey (name, parent);
1496 m.LoadData (node);
1497 nameToMethod [key] = m;
1498 break;
1500 node = node.NextSibling;
1503 base.LoadExtraData (name, orig);
1506 public override string GetNodeKey (string name, XmlNode node)
1508 XmlAttributeCollection atts = node.Attributes;
1509 return String.Format ("{0}:{1}:{2}", atts ["name"].Value,
1510 atts ["ptype"].Value,
1511 atts ["params"].Value);
1514 public override string GroupName {
1515 get { return "properties"; }
1518 public override string Name {
1519 get { return "property"; }
1523 class XMLEvents : XMLMember
1525 Hashtable eventTypes;
1527 protected override void LoadExtraData (string name, XmlNode node)
1529 XmlAttribute xatt = node.Attributes ["eventtype"];
1530 if (xatt != null) {
1531 if (eventTypes == null)
1532 eventTypes = new Hashtable ();
1534 eventTypes [name] = xatt.Value;
1537 base.LoadExtraData (name, node);
1540 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1542 Counters copy = counters;
1543 counters = new Counters ();
1545 try {
1546 base.CompareToInner (name, parent, other);
1547 AddCountersAttributes (parent);
1548 if (eventTypes == null)
1549 return;
1551 XMLEvents evt = (XMLEvents) other;
1552 string etype = eventTypes [name] as string;
1553 string oetype = null;
1554 if (evt.eventTypes != null)
1555 oetype = evt.eventTypes [name] as string;
1557 if (etype != oetype)
1558 AddWarning (parent, "Event type is {0} and should be {1}", oetype, etype);
1559 } finally {
1560 AddCountersAttributes (parent);
1561 copy.AddPartialToPartial (counters);
1562 counters = copy;
1566 protected override string ConvertToString (int att)
1568 EventAttributes ea = (EventAttributes) att;
1569 return ea.ToString ();
1572 public override string GroupName {
1573 get { return "events"; }
1576 public override string Name {
1577 get { return "event"; }
1581 class XMLMethods : XMLMember
1583 Hashtable returnTypes;
1584 Hashtable parameters;
1585 Hashtable genericConstraints;
1586 Hashtable signatureFlags;
1588 [Flags]
1589 enum SignatureFlags
1591 None = 0,
1592 Abstract = 1,
1593 Virtual = 2,
1594 Static = 4
1597 protected override void LoadExtraData (string name, XmlNode node)
1599 XmlAttribute xatt = node.Attributes ["returntype"];
1600 if (xatt != null) {
1601 if (returnTypes == null)
1602 returnTypes = new Hashtable ();
1604 returnTypes [name] = xatt.Value;
1607 SignatureFlags flags = SignatureFlags.None;
1608 if (((XmlElement) node).GetAttribute ("abstract") == "true")
1609 flags |= SignatureFlags.Abstract;
1610 if (((XmlElement) node).GetAttribute ("static") == "true")
1611 flags |= SignatureFlags.Static;
1612 if (((XmlElement) node).GetAttribute ("virtual") == "true")
1613 flags |= SignatureFlags.Virtual;
1614 if (flags != SignatureFlags.None) {
1615 if (signatureFlags == null)
1616 signatureFlags = new Hashtable ();
1617 signatureFlags [name] = flags;
1620 XmlNode parametersNode = node.SelectSingleNode ("parameters");
1621 if (parametersNode != null) {
1622 if (parameters == null)
1623 parameters = new Hashtable ();
1625 XMLParameters parms = new XMLParameters ();
1626 parms.LoadData (parametersNode);
1628 parameters[name] = parms;
1631 XmlNode genericNode = node.SelectSingleNode ("generic-method-constraints");
1632 if (genericNode != null) {
1633 if (genericConstraints == null)
1634 genericConstraints = new Hashtable ();
1635 XMLGenericMethodConstraints csts = new XMLGenericMethodConstraints ();
1636 csts.LoadData (genericNode);
1637 genericConstraints [name] = csts;
1640 base.LoadExtraData (name, node);
1643 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1645 // create backup of actual counters
1646 Counters copy = counters;
1647 // initialize counters for current method
1648 counters = new Counters();
1650 try {
1651 base.CompareToInner(name, parent, other);
1652 XMLMethods methods = (XMLMethods) other;
1654 SignatureFlags flags = signatureFlags != null &&
1655 signatureFlags.ContainsKey (name) ?
1656 (SignatureFlags) signatureFlags [name] :
1657 SignatureFlags.None;
1658 SignatureFlags oflags = methods.signatureFlags != null &&
1659 methods.signatureFlags.ContainsKey (name) ?
1660 (SignatureFlags) methods.signatureFlags [name] :
1661 SignatureFlags.None;
1663 if (flags!= oflags) {
1664 if (flags == SignatureFlags.None)
1665 AddWarning (parent, String.Format ("should not be {0}", oflags));
1666 else if (oflags == SignatureFlags.None)
1667 AddWarning (parent, String.Format ("should be {0}", flags));
1668 else
1669 AddWarning (parent, String.Format ("{0} and should be {1}", oflags, flags));
1672 if (returnTypes != null) {
1673 string rtype = returnTypes[name] as string;
1674 string ortype = null;
1675 if (methods.returnTypes != null)
1676 ortype = methods.returnTypes[name] as string;
1678 if (rtype != ortype)
1679 AddWarning (parent, "Return type is {0} and should be {1}", ortype, rtype);
1682 if (parameters != null) {
1683 XMLParameters parms = parameters[name] as XMLParameters;
1684 parms.CompareTo (document, parent, methods.parameters[name]);
1685 counters.AddPartialToPartial (parms.Counters);
1687 } finally {
1688 // output counter attributes in result document
1689 AddCountersAttributes(parent);
1691 // add temporary counters to actual counters
1692 copy.AddPartialToPartial(counters);
1693 // restore backup of actual counters
1694 counters = copy;
1698 protected override string ConvertToString (int att)
1700 MethodAttributes ma = (MethodAttributes) att;
1701 // ignore ReservedMasks
1702 ma &= ~ MethodAttributes.ReservedMask;
1703 ma &= ~ MethodAttributes.VtableLayoutMask;
1704 if ((ma & MethodAttributes.FamORAssem) != 0)
1705 ma = (ma & ~ MethodAttributes.FamORAssem) | MethodAttributes.Family;
1707 // ignore the HasSecurity attribute for now
1708 if ((ma & MethodAttributes.HasSecurity) != 0)
1709 ma = (MethodAttributes) (att - (int) MethodAttributes.HasSecurity);
1711 // ignore the RequireSecObject attribute for now
1712 if ((ma & MethodAttributes.RequireSecObject) != 0)
1713 ma = (MethodAttributes) (att - (int) MethodAttributes.RequireSecObject);
1715 // we don't care if the implementation is forwarded through PInvoke
1716 if ((ma & MethodAttributes.PinvokeImpl) != 0)
1717 ma = (MethodAttributes) (att - (int) MethodAttributes.PinvokeImpl);
1719 return ma.ToString ();
1722 public override string GroupName {
1723 get { return "methods"; }
1726 public override string Name {
1727 get { return "method"; }
1731 class XMLConstructors : XMLMethods
1733 public override string GroupName {
1734 get { return "constructors"; }
1737 public override string Name {
1738 get { return "constructor"; }
1742 class XmlNodeComparer : IComparer
1744 public static XmlNodeComparer Default = new XmlNodeComparer ();
1746 public int Compare (object a, object b)
1748 XmlNode na = (XmlNode) a;
1749 XmlNode nb = (XmlNode) b;
1750 return String.Compare (na.Attributes ["name"].Value, nb.Attributes ["name"].Value);