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.
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // (C) 2003 Novell, Inc (http://www.novell.com)
12 using System.Collections;
14 using System.Reflection;
18 namespace Mono.AssemblyCompare
22 static int Main (string [] args)
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;
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 ();
46 result.LoadData (node);
47 } catch (Exception e) {
48 Console.Error.WriteLine ("Error loading {0}: {1}\n{2}", file, e.Message, e);
59 public int PresentTotal;
61 public int MissingTotal;
66 public int ExtraTotal;
68 public int WarningTotal;
69 public int ErrorTotal;
75 public void AddPartialToPartial (Counters other)
77 Present += other.Present;
79 Missing += other.Missing;
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;
119 get { return Present + Missing; }
122 public int AbsTotal {
123 get { return PresentTotal + MissingTotal; }
127 get { return Present - Todo; }
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);
149 return sw.GetStringBuilder ().ToString ();
153 abstract class XMLData
155 protected XmlDocument document;
156 protected Counters counters;
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);
177 return (object []) list.ToArray (type);
180 protected void AddAttribute (XmlNode node, string name, string value)
182 XmlAttribute attr = document.CreateAttribute (name);
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 ());
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)
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 ("warnings", 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)
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)) {
294 string key = GetNodeKey (name, n);
295 keys.Add (key, name);
297 LoadExtraData (key, n.FirstChild);
302 protected virtual bool CheckIfAdd (string value)
307 protected virtual void LoadExtraData (string name, XmlNode node)
311 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
315 group = doc.CreateElement (GroupName, null);
317 Hashtable okeys = null;
318 if (other != null && ((XMLNameGroup) other).keys != null) {
319 okeys = ((XMLNameGroup) other).keys;
323 bool onull = (okeys == 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);
337 AddAttribute (node, "presence", "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);
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)
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;
382 public override void LoadData (XmlNode node)
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!");
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) {
425 counters.TodoTotal++;
426 counters.ErrorTotal++;
427 AddAttribute (childA, "error", "todo");
430 AddCountersAttributes (childA);
433 void CompareNamespaces (XmlNode parent, XMLNamespace [] other)
435 ArrayList newNS = new ArrayList ();
436 XmlNode group = document.CreateElement ("namespaces", null);
437 parent.AppendChild (group);
439 Hashtable oh = CreateHash (other);
441 int count = (namespaces == null) ? 0 : namespaces.Length;
442 for (int i = 0; i < count; i++) {
443 XMLNamespace xns = namespaces [i];
445 node = document.CreateElement ("namespace", null);
447 AddAttribute (node, "name", xns.Name);
449 if (oh.ContainsKey (xns.Name)) {
450 int idx = (int) oh [xns.Name];
451 xns.CompareTo (document, node, other [idx]);
453 xns.AddCountersAttributes (node);
455 counters.PresentTotal++;
456 counters.AddPartialToTotal (xns.Counters);
458 AddAttribute (node, "presence", "missing");
460 counters.MissingTotal++;
465 count = other.Length;
466 for (int i = 0; i < count; i++) {
467 XMLNamespace n = other [i];
471 node = document.CreateElement ("namespace", null);
473 AddAttribute (node, "name", n.Name);
475 counters.ExtraTotal++;
479 XmlNode [] nodes = (XmlNode []) newNS.ToArray (typeof (XmlNode));
480 Array.Sort (nodes, XmlNodeComparer.Default);
481 foreach (XmlNode nn in nodes)
482 group.AppendChild (nn);
485 static Hashtable CreateHash (XMLNamespace [] other)
487 Hashtable result = new Hashtable ();
490 foreach (XMLNamespace n in other) {
491 result [n.Name] = i++;
498 public XmlDocument CompareAndGetDocument (XMLAssembly other)
500 XmlDocument doc = new XmlDocument ();
502 XmlNode parent = doc.CreateElement ("assemblies", null);
503 doc.AppendChild (parent);
505 CompareTo (doc, parent, other);
507 XmlNode decl = doc.CreateXmlDeclaration ("1.0", null, null);
508 doc.InsertBefore (decl, doc.DocumentElement);
514 class XMLNamespace : XMLData
519 public override void LoadData (XmlNode node)
522 throw new ArgumentNullException ("node");
524 if (node.Name != "namespace")
525 throw new FormatException ("Expecting <namespace>");
527 name = node.Attributes ["name"].Value;
528 XmlNode classes = node.FirstChild;
529 if (classes == null) {
530 Console.Error.WriteLine ("Warning: no classes for {0}", node.Attributes ["name"]);
534 if (classes.Name != "classes")
535 throw new FormatException ("Expecting <classes>. Got <" + classes.Name + ">");
537 types = (XMLClass []) LoadRecursive (classes.ChildNodes, typeof (XMLClass));
540 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
543 XMLNamespace nspace = (XMLNamespace) other;
545 XmlNode childA = doc.CreateElement ("classes", null);
546 parent.AppendChild (childA);
548 CompareTypes (childA, nspace.types);
551 void CompareTypes (XmlNode parent, XMLClass [] other)
553 ArrayList newNodes = new ArrayList ();
554 Hashtable oh = CreateHash (other);
556 int count = (types == null) ? 0 : types.Length;
557 for (int i = 0; i < count; i++) {
558 XMLClass xclass = types [i];
560 node = document.CreateElement ("class", null);
562 AddAttribute (node, "name", xclass.Name);
563 AddAttribute (node, "type", xclass.Type);
565 if (oh.ContainsKey (xclass.Name)) {
566 int idx = (int) oh [xclass.Name];
567 xclass.CompareTo (document, node, other [idx]);
569 counters.AddPartialToPartial (xclass.Counters);
571 AddAttribute (node, "presence", "missing");
573 counters.MissingTotal++;
578 count = other.Length;
579 for (int i = 0; i < count; i++) {
580 XMLClass c = other [i];
581 if (c == null || c.Name == "MonoTODOAttribute")
584 node = document.CreateElement ("class", null);
586 AddAttribute (node, "name", c.Name);
587 AddAttribute (node, "type", c.Type);
590 counters.ExtraTotal++;
594 XmlNode [] nodes = (XmlNode []) newNodes.ToArray (typeof (XmlNode));
595 Array.Sort (nodes, XmlNodeComparer.Default);
596 foreach (XmlNode nn in nodes)
597 parent.AppendChild (nn);
600 static Hashtable CreateHash (XMLClass [] other)
602 Hashtable result = new Hashtable ();
605 foreach (XMLClass c in other) {
606 result [c.Name] = i++;
618 class XMLClass : XMLData
624 XMLAttributes attributes;
625 XMLInterfaces interfaces;
627 XMLConstructors constructors;
628 XMLProperties properties;
633 public override void LoadData (XmlNode node)
636 throw new ArgumentNullException ("node");
638 name = node.Attributes ["name"].Value;
639 type = node.Attributes ["type"].Value;
640 XmlAttribute xatt = node.Attributes ["base"];
642 baseName = xatt.Value;
644 xatt = node.Attributes ["sealed"];
645 isSealed = (xatt != null && xatt.Value == "true");
647 XmlNode child = node.FirstChild;
649 // Console.Error.WriteLine ("Empty class {0} {1}", name, type);
653 if (child.Name == "attributes") {
654 attributes = new XMLAttributes ();
655 attributes.LoadData (child);
656 child = child.NextSibling;
659 if (child != null && child.Name == "interfaces") {
660 interfaces = new XMLInterfaces ();
661 interfaces.LoadData (child);
662 child = child.NextSibling;
665 if (child != null && child.Name == "fields") {
666 fields = new XMLFields ();
667 fields.LoadData (child);
668 child = child.NextSibling;
671 if (child != null && child.Name == "constructors") {
672 constructors = new XMLConstructors ();
673 constructors.LoadData (child);
674 child = child.NextSibling;
677 if (child != null && child.Name == "properties") {
678 properties = new XMLProperties ();
679 properties.LoadData (child);
680 child = child.NextSibling;
683 if (child != null && child.Name == "events") {
684 events = new XMLEvents ();
685 events.LoadData (child);
686 child = child.NextSibling;
689 if (child != null && child.Name == "methods") {
690 methods = new XMLMethods ();
691 methods.LoadData (child);
692 child = child.NextSibling;
698 if (child.Name != "classes") {
699 Console.WriteLine ("name: {0} type: {1} {2}", name, type, child.NodeType);
700 throw new FormatException ("Expecting <classes>. Got <" + child.Name + ">");
703 nested = (XMLClass []) LoadRecursive (child.ChildNodes, typeof (XMLClass));
706 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
709 XMLClass oclass = (XMLClass) other;
711 if (attributes != null || oclass.attributes != null) {
712 if (attributes == null)
713 attributes = new XMLAttributes ();
715 attributes.CompareTo (doc, parent, oclass.attributes);
716 counters.AddPartialToPartial (attributes.Counters);
717 if (oclass.attributes != null && oclass.attributes.IsTodo) {
719 counters.TodoTotal++;
720 counters.ErrorTotal++;
721 AddAttribute (parent, "error", "todo");
725 if (type != oclass.type)
726 AddWarning (parent, "Class type is wrong: {0} != {1}", type, oclass.type);
728 if (baseName != oclass.baseName)
729 AddWarning (parent, "Base class is wrong: {0} != {1}", baseName, oclass.baseName);
731 if (isSealed != oclass.isSealed)
732 AddWarning (parent, "Should {0}be sealed", isSealed ? "" : "not ");
734 if (interfaces != null || oclass.interfaces != null) {
735 if (interfaces == null)
736 interfaces = new XMLInterfaces ();
738 interfaces.CompareTo (doc, parent, oclass.interfaces);
739 counters.AddPartialToPartial (interfaces.Counters);
742 if (fields != null || oclass.fields != null) {
744 fields = new XMLFields ();
746 fields.CompareTo (doc, parent, oclass.fields);
747 counters.AddPartialToPartial (fields.Counters);
750 if (constructors != null || oclass.constructors != null) {
751 if (constructors == null)
752 constructors = new XMLConstructors ();
754 constructors.CompareTo (doc, parent, oclass.constructors);
755 counters.AddPartialToPartial (constructors.Counters);
758 if (properties != null || oclass.properties != null) {
759 if (properties == null)
760 properties = new XMLProperties ();
762 properties.CompareTo (doc, parent, oclass.properties);
763 counters.AddPartialToPartial (properties.Counters);
766 if (events != null || oclass.events != null) {
768 events = new XMLEvents ();
770 events.CompareTo (doc, parent, oclass.events);
771 counters.AddPartialToPartial (events.Counters);
774 if (methods != null || oclass.methods != null) {
776 methods = new XMLMethods ();
778 methods.CompareTo (doc, parent, oclass.methods);
779 counters.AddPartialToPartial (methods.Counters);
782 if (nested != null || oclass.nested != null) {
783 XmlNode n = doc.CreateElement ("classes", null);
784 parent.AppendChild (n);
785 CompareTypes (n, oclass.nested);
788 AddCountersAttributes (parent);
791 void CompareTypes (XmlNode parent, XMLClass [] other)
793 ArrayList newNodes = new ArrayList ();
794 Hashtable oh = CreateHash (other);
796 int count = (nested == null) ? 0 : nested.Length;
797 for (int i = 0; i < count; i++) {
798 XMLClass xclass = nested [i];
800 node = document.CreateElement ("nestedclass", null);
802 AddAttribute (node, "name", xclass.Name);
803 AddAttribute (node, "type", xclass.Type);
805 if (oh.ContainsKey (xclass.Name)) {
806 int idx = (int) oh [xclass.Name];
807 xclass.CompareTo (document, node, other [idx]);
809 counters.AddPartialToPartial (xclass.Counters);
811 // TODO: Should I count here?
812 AddAttribute (node, "presence", "missing");
814 counters.MissingTotal++;
819 count = other.Length;
820 for (int i = 0; i < count; i++) {
821 XMLClass c = other [i];
822 if (c == null || c.Name == "MonoTODOAttribute")
825 node = document.CreateElement ("nestedclass", null);
827 AddAttribute (node, "name", c.Name);
830 counters.ExtraTotal++;
834 XmlNode [] nodes = (XmlNode []) newNodes.ToArray (typeof (XmlNode));
835 Array.Sort (nodes, XmlNodeComparer.Default);
836 foreach (XmlNode nn in nodes)
837 parent.AppendChild (nn);
840 static Hashtable CreateHash (XMLClass [] other)
842 Hashtable result = new Hashtable ();
845 foreach (XMLClass c in other) {
846 result [c.Name] = i++;
862 class XMLAttributes : XMLNameGroup
866 protected override bool CheckIfAdd (string value)
868 if (value.EndsWith (".MonoTODOAttribute")) {
876 public override string GetNodeKey (string name, XmlNode node)
879 while (keys.ContainsKey (name)) {
880 name = String.Format ("{0}:{1}", name, i++);
886 public override string GroupName {
887 get { return "attributes"; }
890 public override string Name {
891 get { return "attribute"; }
895 get { return isTodo; }
899 class XMLInterfaces : XMLNameGroup
901 public override string GroupName {
902 get { return "interfaces"; }
905 public override string Name {
906 get { return "interface"; }
910 abstract class XMLMember : XMLNameGroup
912 Hashtable attributeMap;
913 Hashtable access = new Hashtable ();
915 protected override void LoadExtraData (string name, XmlNode node)
917 XmlAttribute xatt = node.Attributes ["attrib"];
919 access [name] = xatt.Value;
922 while (node != null) {
923 if (node != null && node.Name == "attributes") {
924 XMLAttributes a = new XMLAttributes ();
926 if (attributeMap == null)
927 attributeMap = new Hashtable ();
929 attributeMap [name] = a;
932 node = node.NextSibling;
935 base.LoadExtraData (name, orig);
938 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
940 base.CompareToInner (name, parent, other);
941 XMLMember mb = other as XMLMember;
942 XMLAttributes att = null;
943 XMLAttributes oatt = null;
944 if (attributeMap != null)
945 att = attributeMap [name] as XMLAttributes;
947 if (mb != null && mb.attributeMap != null)
948 oatt = mb.attributeMap [name] as XMLAttributes;
950 if (att != null || oatt != null) {
952 att = new XMLAttributes ();
954 att.CompareTo (document, parent, oatt);
955 counters.AddPartialToTotal (att.Counters);
956 if (oatt != null && oatt.IsTodo) {
958 counters.ErrorTotal++;
959 AddAttribute (parent, "error", "todo");
966 XMLMember member = (XMLMember) other;
967 string acc = access [name] as string;
972 if (member.access != null)
973 oacc = member.access [name] as string;
975 string accName = ConvertToString (Int32.Parse (acc));
976 string oaccName = "";
978 oaccName = ConvertToString (Int32.Parse (oacc));
980 AddWarning (parent, "Incorrect attributes: '{0}' != '{1}'", accName, oaccName);
983 protected virtual string ConvertToString (int att)
989 class XMLFields : XMLMember
991 Hashtable fieldTypes;
993 protected override void LoadExtraData (string name, XmlNode node)
995 XmlAttribute xatt = node.Attributes ["fieldtype"];
997 if (fieldTypes == null)
998 fieldTypes = new Hashtable ();
1000 fieldTypes [name] = xatt.Value;
1003 base.LoadExtraData (name, node);
1006 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1008 base.CompareToInner (name, parent, other);
1009 if (fieldTypes == null)
1012 XMLFields fields = (XMLFields) other;
1013 string ftype = fieldTypes [name] as string;
1014 string oftype = null;
1015 if (fields.fieldTypes != null)
1016 oftype = fields.fieldTypes [name] as string;
1018 AddWarning (parent, "Field type is {0} and should be {1}", oftype, ftype);
1021 protected override string ConvertToString (int att)
1023 FieldAttributes fa = (FieldAttributes) att;
1024 return fa.ToString ();
1027 public override string GroupName {
1028 get { return "fields"; }
1031 public override string Name {
1032 get { return "field"; }
1036 class XMLProperties : XMLMember
1038 Hashtable nameToMethod = new Hashtable ();
1040 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1042 XMLProperties oprop = other as XMLProperties;
1043 if (oprop != null) {
1044 XMLMethods m = nameToMethod [name] as XMLMethods;
1045 XMLMethods om = oprop.nameToMethod [name] as XMLMethods;
1046 if (m != null || om != null) {
1048 m = new XMLMethods ();
1050 Counters copy = counters;
1051 m.CompareTo (document, parent, om);
1052 counters = new Counters ();
1053 counters.AddPartialToPartial (m.Counters);
1054 AddCountersAttributes (parent);
1056 counters.AddPartialToPartial (m.Counters);
1060 base.CompareToInner (name, parent, other);
1063 protected override void LoadExtraData (string name, XmlNode node)
1065 XmlNode orig = node;
1066 while (node != null) {
1067 if (node != null && node.Name == "methods") {
1068 XMLMethods m = new XMLMethods ();
1069 XmlNode parent = node.ParentNode;
1070 string key = GetNodeKey (name, parent);
1072 nameToMethod [key] = m;
1075 node = node.NextSibling;
1078 base.LoadExtraData (name, orig);
1081 public override string GetNodeKey (string name, XmlNode node)
1083 XmlAttributeCollection atts = node.Attributes;
1084 return String.Format ("{0}:{1}:{2}", atts ["name"].Value,
1085 atts ["ptype"].Value,
1086 atts ["params"].Value);
1089 public override string GroupName {
1090 get { return "properties"; }
1093 public override string Name {
1094 get { return "property"; }
1098 class XMLEvents : XMLMember
1100 Hashtable eventTypes;
1102 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
1104 base.CompareTo (doc, parent, other);
1105 AddCountersAttributes (parent);
1108 protected override void LoadExtraData (string name, XmlNode node)
1110 XmlAttribute xatt = node.Attributes ["eventtype"];
1112 if (eventTypes == null)
1113 eventTypes = new Hashtable ();
1115 eventTypes [name] = xatt.Value;
1118 base.LoadExtraData (name, node);
1121 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1123 base.CompareToInner (name, parent, other);
1124 if (eventTypes == null)
1127 XMLEvents evt = (XMLEvents) other;
1128 string etype = eventTypes [name] as string;
1129 string oetype = null;
1130 if (evt.eventTypes != null)
1131 oetype = evt.eventTypes [name] as string;
1133 AddWarning (parent, "Event type is {0} and should be {1}", oetype, etype);
1136 protected override string ConvertToString (int att)
1138 EventAttributes ea = (EventAttributes) att;
1139 return ea.ToString ();
1142 public override string GroupName {
1143 get { return "events"; }
1146 public override string Name {
1147 get { return "event"; }
1151 class XMLMethods : XMLMember
1153 Hashtable returnTypes;
1155 protected override void LoadExtraData (string name, XmlNode node)
1157 XmlAttribute xatt = node.Attributes ["returntype"];
1159 if (returnTypes == null)
1160 returnTypes = new Hashtable ();
1162 returnTypes [name] = xatt.Value;
1165 base.LoadExtraData (name, node);
1168 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1170 base.CompareToInner (name, parent, other);
1171 if (returnTypes == null)
1174 XMLMethods methods = (XMLMethods) other;
1175 string rtype = returnTypes [name] as string;
1176 string ortype = null;
1177 if (methods.returnTypes != null)
1178 ortype = methods.returnTypes [name] as string;
1180 AddWarning (parent, "Event type is {0} and should be {1}", ortype, rtype);
1183 protected override string ConvertToString (int att)
1185 MethodAttributes ma = (MethodAttributes) att;
1186 return ma.ToString ();
1189 public override string GroupName {
1190 get { return "methods"; }
1193 public override string Name {
1194 get { return "method"; }
1198 class XMLConstructors : XMLMethods
1200 public override string GroupName {
1201 get { return "constructors"; }
1204 public override string Name {
1205 get { return "constructor"; }
1209 class XmlNodeComparer : IComparer
1211 public static XmlNodeComparer Default = new XmlNodeComparer ();
1213 public int Compare (object a, object b)
1215 XmlNode na = (XmlNode) a;
1216 XmlNode nb = (XmlNode) b;
1217 return String.Compare (na.Attributes ["name"].Value, nb.Attributes ["name"].Value);