5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // (C) 2003 Novell, Inc (http://www.novell.com)
11 using System.Collections;
13 using System.Reflection;
17 namespace Mono.AssemblyCompare
21 static int Main (string [] args)
26 XMLAssembly ms = CreateXMLAssembly (args [0]);
27 XMLAssembly mono = CreateXMLAssembly (args [1]);
28 XmlDocument doc = ms.CompareAndGetDocument (mono);
30 XmlTextWriter writer = new XmlTextWriter (Console.Out);
31 writer.Formatting = Formatting.Indented;
37 static XMLAssembly CreateXMLAssembly (string file)
39 XmlDocument doc = new XmlDocument ();
40 doc.Load (File.OpenRead (file));
42 XmlNode node = doc.SelectSingleNode ("/assemblies/assembly");
43 XMLAssembly result = new XMLAssembly ();
45 result.LoadData (node);
46 } catch (Exception e) {
47 Console.Error.WriteLine ("Error loading {0}: {1}\n{2}", file, e.Message, e);
58 public int PresentTotal;
60 public int MissingTotal;
65 public int ExtraTotal;
67 public int WarningTotal;
68 public int ErrorTotal;
74 public void AddPartialToPartial (Counters other)
76 Present += other.Present;
78 Missing += other.Missing;
81 Warning += other.Warning;
82 AddPartialToTotal (other);
85 public void AddPartialToTotal (Counters other)
87 PresentTotal += other.Present;
88 ExtraTotal += other.Extra;
89 MissingTotal += other.Missing;
91 TodoTotal += other.Todo;
92 WarningTotal += other.Warning;
95 public void AddTotalToPartial (Counters other)
97 Present += other.PresentTotal;
98 Extra += other.ExtraTotal;
99 Missing += other.MissingTotal;
101 Todo += other.TodoTotal;
102 Warning += other.WarningTotal;
103 AddTotalToTotal (other);
106 public void AddTotalToTotal (Counters other)
108 PresentTotal += other.PresentTotal;
109 ExtraTotal += other.ExtraTotal;
110 MissingTotal += other.MissingTotal;
112 TodoTotal += other.TodoTotal;
113 WarningTotal += other.WarningTotal;
114 ErrorTotal += other.ErrorTotal;
118 get { return Present + Missing; }
121 public int AbsTotal {
122 get { return PresentTotal + MissingTotal; }
126 get { return Present - Todo; }
130 get { return PresentTotal - TodoTotal - ErrorTotal; }
133 public override string ToString ()
135 StringWriter sw = new StringWriter ();
136 sw.WriteLine ("Present: {0}", Present);
137 sw.WriteLine ("PresentTotal: {0}", PresentTotal);
138 sw.WriteLine ("Missing: {0}", Missing);
139 sw.WriteLine ("MissingTotal: {0}", MissingTotal);
140 sw.WriteLine ("Todo: {0}", Todo);
141 sw.WriteLine ("TodoTotal: {0}", TodoTotal);
142 sw.WriteLine ("Extra: {0}", Extra);
143 sw.WriteLine ("ExtraTotal: {0}", ExtraTotal);
144 sw.WriteLine ("Warning: {0}", Warning);
145 sw.WriteLine ("WarningTotal: {0}", WarningTotal);
146 sw.WriteLine ("ErrorTotal: {0}", ErrorTotal);
148 return sw.GetStringBuilder ().ToString ();
152 abstract class XMLData
154 protected XmlDocument document;
155 protected Counters counters;
160 counters = new Counters ();
163 public virtual void LoadData (XmlNode node)
167 protected object [] LoadRecursive (XmlNodeList nodeList, Type type)
169 ArrayList list = new ArrayList ();
170 foreach (XmlNode node in nodeList) {
171 XMLData data = (XMLData) Activator.CreateInstance (type);
172 data.LoadData (node);
176 return (object []) list.ToArray (type);
179 protected void AddAttribute (XmlNode node, string name, string value)
181 XmlAttribute attr = document.CreateAttribute (name);
183 node.Attributes.Append (attr);
186 protected void AddExtra (XmlNode node)
188 AddAttribute (node, "presence", "extra");
189 AddAttribute (node, "ok", "1");
190 AddAttribute (node, "ok_total", "1");
191 AddAttribute (node, "extra_total", "1");
194 public void AddCountersAttributes (XmlNode node)
196 if (counters.Missing > 0)
197 AddAttribute (node, "missing", counters.Missing.ToString ());
199 if (counters.Present > 0)
200 AddAttribute (node, "present", counters.Present.ToString ());
202 if (counters.Extra > 0)
203 AddAttribute (node, "extra", counters.Extra.ToString ());
206 AddAttribute (node, "ok", counters.Ok.ToString ());
208 if (counters.Total > 0) {
209 int percent = (100 * counters.Ok / counters.Total);
210 AddAttribute (node, "complete", percent.ToString ());
213 if (counters.Todo > 0)
214 AddAttribute (node, "todo", counters.Todo.ToString ());
216 if (counters.Warning > 0)
217 AddAttribute (node, "warning", counters.Warning.ToString ());
219 if (counters.MissingTotal > 0)
220 AddAttribute (node, "missing_total", counters.MissingTotal.ToString ());
222 if (counters.PresentTotal > 0)
223 AddAttribute (node, "present_total", counters.PresentTotal.ToString ());
225 if (counters.ExtraTotal > 0)
226 AddAttribute (node, "extra_total", counters.ExtraTotal.ToString ());
228 if (counters.OkTotal > 0)
229 AddAttribute (node, "ok_total", counters.OkTotal.ToString ());
231 if (counters.AbsTotal > 0) {
232 int percent = (100 * counters.OkTotal / counters.AbsTotal);
233 AddAttribute (node, "complete_total", percent.ToString ());
236 if (counters.TodoTotal > 0) {
237 AddAttribute (node, "todo_total", counters.TodoTotal.ToString ());
238 //TODO: should be different on error. check error cases in corcompare.
239 AddAttribute (node, "error_total", counters.Todo.ToString ());
242 if (counters.WarningTotal > 0)
243 AddAttribute (node, "warning_total", counters.WarningTotal.ToString ());
247 protected void AddWarning (XmlNode parent, string fmt, params object [] args)
251 XmlNode warnings = parent.SelectSingleNode ("warnings");
252 if (warnings == null) {
253 warnings = document.CreateElement ("warnings", null);
254 parent.AppendChild (warnings);
257 AddAttribute (parent, "error", "warning");
258 XmlNode warning = document.CreateElement ("warnings", null);
259 AddAttribute (warning, "text", String.Format (fmt, args));
260 warnings.AppendChild (warning);
263 public bool HaveWarnings {
264 get { return haveWarnings; }
267 public Counters Counters {
268 get { return counters; }
271 public abstract void CompareTo (XmlDocument doc, XmlNode parent, object other);
274 abstract class XMLNameGroup : XMLData
276 protected XmlNode group;
277 protected Hashtable keys;
279 public override void LoadData (XmlNode node)
282 throw new ArgumentNullException ("node");
284 if (node.Name != GroupName)
285 throw new FormatException (String.Format ("Expecting <{0}>", GroupName));
287 keys = new Hashtable ();
288 foreach (XmlNode n in node.ChildNodes) {
289 string name = n.Attributes ["name"].Value;
290 if (CheckIfAdd (name)) {
291 string key = GetNodeKey (name, n);
292 keys.Add (key, name);
294 LoadExtraData (key, n.FirstChild);
299 protected virtual bool CheckIfAdd (string value)
304 protected virtual void LoadExtraData (string name, XmlNode node)
308 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
312 group = doc.CreateElement (GroupName, null);
314 Hashtable okeys = null;
315 if (other != null && ((XMLNameGroup) other).keys != null) {
316 okeys = ((XMLNameGroup) other).keys;
320 bool onull = (okeys == null);
322 foreach (DictionaryEntry entry in keys) {
323 node = doc.CreateElement (Name, null);
324 group.AppendChild (node);
325 string key = (string) entry.Key;
326 string name = (string) entry.Value;
327 AddAttribute (node, "name", name);
329 if (!onull && HasKey (key, okeys)) {
330 CompareToInner (key, node, (XMLNameGroup) other);
334 AddAttribute (node, "presence", "missing");
340 if (!onull && okeys.Count != 0) {
341 foreach (string value in okeys.Values) {
342 node = doc.CreateElement (Name, null);
343 AddAttribute (node, "name", (string) value);
344 AddAttribute (node, "presence", "extra");
345 group.AppendChild (node);
350 if (group.HasChildNodes)
351 parent.AppendChild (group);
354 protected virtual void CompareToInner (string name, XmlNode node, XMLNameGroup other)
358 public virtual string GetNodeKey (string name, XmlNode node)
363 public virtual bool HasKey (string key, Hashtable other)
365 return other.ContainsKey (key);
368 public abstract string GroupName { get; }
369 public abstract string Name { get; }
372 class XMLAssembly : XMLData
374 XMLAttributes attributes;
375 XMLNamespace [] namespaces;
379 public override void LoadData (XmlNode node)
382 throw new ArgumentNullException ("node");
384 name = node.Attributes ["name"].Value;
385 version = node.Attributes ["version"].Value;
386 XmlNode atts = node.FirstChild;
387 attributes = new XMLAttributes ();
388 if (atts.Name == "attributes") {
389 attributes.LoadData (atts);
390 atts = atts.NextSibling;
393 if (atts == null || atts.Name != "namespaces") {
394 Console.Error.WriteLine ("Warning: no namespaces found!");
398 namespaces = (XMLNamespace []) LoadRecursive (atts.ChildNodes, typeof (XMLNamespace));
401 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
403 XMLAssembly assembly = (XMLAssembly) other;
405 XmlNode childA = doc.CreateElement ("assembly", null);
406 AddAttribute (childA, "name", name);
407 AddAttribute (childA, "version", version);
408 if (name != assembly.name)
409 AddWarning (childA, "Assembly names not equal: {0}, {1}", name, assembly.name);
411 if (version != assembly.version)
412 AddWarning (childA, "Assembly version not equal: {0}, {1}", version, assembly.version);
414 parent.AppendChild (childA);
416 attributes.CompareTo (doc, childA, assembly.attributes);
417 counters.AddPartialToPartial (attributes.Counters);
419 CompareNamespaces (childA, assembly.namespaces);
420 if (assembly.attributes != null && assembly.attributes.IsTodo) {
422 counters.TodoTotal++;
423 counters.ErrorTotal++;
424 AddAttribute (childA, "error", "todo");
427 AddCountersAttributes (childA);
430 void CompareNamespaces (XmlNode parent, XMLNamespace [] other)
432 ArrayList newNS = new ArrayList ();
433 XmlNode group = document.CreateElement ("namespaces", null);
434 parent.AppendChild (group);
436 Hashtable oh = CreateHash (other);
438 int count = (namespaces == null) ? 0 : namespaces.Length;
439 for (int i = 0; i < count; i++) {
440 XMLNamespace xns = namespaces [i];
442 node = document.CreateElement ("namespace", null);
444 AddAttribute (node, "name", xns.Name);
446 if (oh.ContainsKey (xns.Name)) {
447 int idx = (int) oh [xns.Name];
448 xns.CompareTo (document, node, other [idx]);
450 xns.AddCountersAttributes (node);
452 counters.PresentTotal++;
453 counters.AddPartialToTotal (xns.Counters);
455 AddAttribute (node, "presence", "missing");
457 counters.MissingTotal++;
462 count = other.Length;
463 for (int i = 0; i < count; i++) {
464 XMLNamespace n = other [i];
468 node = document.CreateElement ("namespace", null);
470 AddAttribute (node, "name", n.Name);
472 counters.ExtraTotal++;
476 XmlNode [] nodes = (XmlNode []) newNS.ToArray (typeof (XmlNode));
477 Array.Sort (nodes, XmlNodeComparer.Default);
478 foreach (XmlNode nn in nodes)
479 group.AppendChild (nn);
482 static Hashtable CreateHash (XMLNamespace [] other)
484 Hashtable result = new Hashtable ();
487 foreach (XMLNamespace n in other) {
488 result [n.Name] = i++;
495 public XmlDocument CompareAndGetDocument (XMLAssembly other)
497 XmlDocument doc = new XmlDocument ();
499 XmlNode parent = doc.CreateElement ("assemblies", null);
500 doc.AppendChild (parent);
502 CompareTo (doc, parent, other);
504 XmlNode decl = doc.CreateXmlDeclaration ("1.0", null, null);
505 doc.InsertBefore (decl, doc.DocumentElement);
511 class XMLNamespace : XMLData
516 public override void LoadData (XmlNode node)
519 throw new ArgumentNullException ("node");
521 if (node.Name != "namespace")
522 throw new FormatException ("Expecting <namespace>");
524 name = node.Attributes ["name"].Value;
525 XmlNode classes = node.FirstChild;
526 if (classes == null) {
527 Console.Error.WriteLine ("Warning: no classes for {0}", node.Attributes ["name"]);
531 if (classes.Name != "classes")
532 throw new FormatException ("Expecting <classes>. Got <" + classes.Name + ">");
534 types = (XMLClass []) LoadRecursive (classes.ChildNodes, typeof (XMLClass));
537 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
540 XMLNamespace nspace = (XMLNamespace) other;
542 XmlNode childA = doc.CreateElement ("classes", null);
543 parent.AppendChild (childA);
545 CompareTypes (childA, nspace.types);
548 void CompareTypes (XmlNode parent, XMLClass [] other)
550 ArrayList newNodes = new ArrayList ();
551 Hashtable oh = CreateHash (other);
553 int count = (types == null) ? 0 : types.Length;
554 for (int i = 0; i < count; i++) {
555 XMLClass xclass = types [i];
557 node = document.CreateElement ("class", null);
559 AddAttribute (node, "name", xclass.Name);
560 AddAttribute (node, "type", xclass.Type);
562 if (oh.ContainsKey (xclass.Name)) {
563 int idx = (int) oh [xclass.Name];
564 xclass.CompareTo (document, node, other [idx]);
566 counters.AddPartialToPartial (xclass.Counters);
568 AddAttribute (node, "presence", "missing");
570 counters.MissingTotal++;
575 count = other.Length;
576 for (int i = 0; i < count; i++) {
577 XMLClass c = other [i];
578 if (c == null || c.Name == "MonoTODOAttribute")
581 node = document.CreateElement ("class", null);
583 AddAttribute (node, "name", c.Name);
586 counters.ExtraTotal++;
590 XmlNode [] nodes = (XmlNode []) newNodes.ToArray (typeof (XmlNode));
591 Array.Sort (nodes, XmlNodeComparer.Default);
592 foreach (XmlNode nn in nodes)
593 parent.AppendChild (nn);
596 static Hashtable CreateHash (XMLClass [] other)
598 Hashtable result = new Hashtable ();
601 foreach (XMLClass c in other) {
602 result [c.Name] = i++;
614 class XMLClass : XMLData
620 XMLAttributes attributes;
621 XMLInterfaces interfaces;
623 XMLConstructors constructors;
624 XMLProperties properties;
629 public override void LoadData (XmlNode node)
632 throw new ArgumentNullException ("node");
634 name = node.Attributes ["name"].Value;
635 type = node.Attributes ["type"].Value;
636 XmlAttribute xatt = node.Attributes ["base"];
638 baseName = xatt.Value;
640 xatt = node.Attributes ["sealed"];
641 isSealed = (xatt != null && xatt.Value == "true");
643 XmlNode child = node.FirstChild;
645 // Console.Error.WriteLine ("Empty class {0} {1}", name, type);
649 if (child.Name == "attributes") {
650 attributes = new XMLAttributes ();
651 attributes.LoadData (child);
652 child = child.NextSibling;
655 if (child != null && child.Name == "interfaces") {
656 interfaces = new XMLInterfaces ();
657 interfaces.LoadData (child);
658 child = child.NextSibling;
661 if (child != null && child.Name == "fields") {
662 fields = new XMLFields ();
663 fields.LoadData (child);
664 child = child.NextSibling;
667 if (child != null && child.Name == "constructors") {
668 constructors = new XMLConstructors ();
669 constructors.LoadData (child);
670 child = child.NextSibling;
673 if (child != null && child.Name == "properties") {
674 properties = new XMLProperties ();
675 properties.LoadData (child);
676 child = child.NextSibling;
679 if (child != null && child.Name == "events") {
680 events = new XMLEvents ();
681 events.LoadData (child);
682 child = child.NextSibling;
685 if (child != null && child.Name == "methods") {
686 methods = new XMLMethods ();
687 methods.LoadData (child);
688 child = child.NextSibling;
694 if (child.Name != "classes") {
695 Console.WriteLine ("name: {0} type: {1} {2}", name, type, child.NodeType);
696 throw new FormatException ("Expecting <classes>. Got <" + child.Name + ">");
699 nested = (XMLClass []) LoadRecursive (child.ChildNodes, typeof (XMLClass));
702 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
705 XMLClass oclass = (XMLClass) other;
707 if (attributes != null || oclass.attributes != null) {
708 if (attributes == null)
709 attributes = new XMLAttributes ();
711 attributes.CompareTo (doc, parent, oclass.attributes);
712 counters.AddPartialToPartial (attributes.Counters);
713 if (oclass.attributes != null && oclass.attributes.IsTodo) {
715 counters.TodoTotal++;
716 counters.ErrorTotal++;
717 AddAttribute (parent, "error", "todo");
721 if (type != oclass.type)
722 AddWarning (parent, "Class type is wrong: {0} != {1}", type, oclass.type);
724 if (baseName != oclass.baseName)
725 AddWarning (parent, "Base class is wrong: {0} != {1}", baseName, oclass.baseName);
727 if (isSealed != oclass.isSealed)
728 AddWarning (parent, "Should {0}be sealed", isSealed ? "" : "not ");
730 if (interfaces != null || oclass.interfaces != null) {
731 if (interfaces == null)
732 interfaces = new XMLInterfaces ();
734 interfaces.CompareTo (doc, parent, oclass.interfaces);
735 counters.AddPartialToPartial (interfaces.Counters);
738 if (fields != null || oclass.fields != null) {
740 fields = new XMLFields ();
742 fields.CompareTo (doc, parent, oclass.fields);
743 counters.AddPartialToPartial (fields.Counters);
746 if (constructors != null || oclass.constructors != null) {
747 if (constructors == null)
748 constructors = new XMLConstructors ();
750 constructors.CompareTo (doc, parent, oclass.constructors);
751 counters.AddPartialToPartial (constructors.Counters);
754 if (properties != null || oclass.properties != null) {
755 if (properties == null)
756 properties = new XMLProperties ();
758 properties.CompareTo (doc, parent, oclass.properties);
759 counters.AddPartialToPartial (properties.Counters);
762 if (events != null || oclass.events != null) {
764 events = new XMLEvents ();
766 events.CompareTo (doc, parent, oclass.events);
767 counters.AddPartialToPartial (events.Counters);
770 if (methods != null || oclass.methods != null) {
772 methods = new XMLMethods ();
774 methods.CompareTo (doc, parent, oclass.methods);
775 counters.AddPartialToPartial (methods.Counters);
778 if (nested != null || oclass.nested != null) {
779 XmlNode n = doc.CreateElement ("classes", null);
780 parent.AppendChild (n);
781 CompareTypes (n, oclass.nested);
784 AddCountersAttributes (parent);
787 void CompareTypes (XmlNode parent, XMLClass [] other)
789 ArrayList newNodes = new ArrayList ();
790 Hashtable oh = CreateHash (other);
792 int count = (nested == null) ? 0 : nested.Length;
793 for (int i = 0; i < count; i++) {
794 XMLClass xclass = nested [i];
796 node = document.CreateElement ("nestedclass", null);
798 AddAttribute (node, "name", xclass.Name);
799 AddAttribute (node, "type", xclass.Type);
801 if (oh.ContainsKey (xclass.Name)) {
802 int idx = (int) oh [xclass.Name];
803 xclass.CompareTo (document, node, other [idx]);
805 counters.AddPartialToPartial (xclass.Counters);
807 // TODO: Should I count here?
808 AddAttribute (node, "presence", "missing");
810 counters.MissingTotal++;
815 count = other.Length;
816 for (int i = 0; i < count; i++) {
817 XMLClass c = other [i];
818 if (c == null || c.Name == "MonoTODOAttribute")
821 node = document.CreateElement ("nestedclass", null);
823 AddAttribute (node, "name", c.Name);
826 counters.ExtraTotal++;
830 XmlNode [] nodes = (XmlNode []) newNodes.ToArray (typeof (XmlNode));
831 Array.Sort (nodes, XmlNodeComparer.Default);
832 foreach (XmlNode nn in nodes)
833 parent.AppendChild (nn);
836 static Hashtable CreateHash (XMLClass [] other)
838 Hashtable result = new Hashtable ();
841 foreach (XMLClass c in other) {
842 result [c.Name] = i++;
858 class XMLAttributes : XMLNameGroup
862 protected override bool CheckIfAdd (string value)
864 if (value.EndsWith (".MonoTODOAttribute")) {
872 public override string GetNodeKey (string name, XmlNode node)
875 while (keys.ContainsKey (name)) {
876 name = String.Format ("{0}:{1}", name, i++);
882 public override string GroupName {
883 get { return "attributes"; }
886 public override string Name {
887 get { return "attribute"; }
891 get { return isTodo; }
895 class XMLInterfaces : XMLNameGroup
897 public override string GroupName {
898 get { return "interfaces"; }
901 public override string Name {
902 get { return "interface"; }
906 abstract class XMLMember : XMLNameGroup
908 Hashtable attributeMap;
909 Hashtable access = new Hashtable ();
911 protected override void LoadExtraData (string name, XmlNode node)
913 XmlAttribute xatt = node.Attributes ["attrib"];
915 access [name] = xatt.Value;
918 while (node != null) {
919 if (node != null && node.Name == "attributes") {
920 XMLAttributes a = new XMLAttributes ();
922 if (attributeMap == null)
923 attributeMap = new Hashtable ();
925 attributeMap [name] = a;
928 node = node.NextSibling;
931 base.LoadExtraData (name, orig);
934 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
936 base.CompareToInner (name, parent, other);
937 XMLMember mb = other as XMLMember;
938 XMLAttributes att = null;
939 XMLAttributes oatt = null;
940 if (attributeMap != null)
941 att = attributeMap [name] as XMLAttributes;
943 if (mb != null && mb.attributeMap != null)
944 oatt = mb.attributeMap [name] as XMLAttributes;
946 if (att != null || oatt != null) {
948 att = new XMLAttributes ();
950 att.CompareTo (document, group, oatt);
951 counters.AddPartialToTotal (att.Counters);
952 if (oatt != null && oatt.IsTodo) {
954 counters.ErrorTotal++;
955 AddAttribute (parent, "error", "todo");
962 XMLMember member = (XMLMember) other;
963 string acc = access [name] as string;
968 if (member.access != null)
969 oacc = member.access [name] as string;
971 string accName = ConvertToString (Int32.Parse (acc));
972 string oaccName = "";
974 oaccName = ConvertToString (Int32.Parse (oacc));
976 AddWarning (parent, "Incorrect attributes: '{0}' != '{1}'", accName, oaccName);
979 protected virtual string ConvertToString (int att)
985 class XMLFields : XMLMember
987 Hashtable fieldTypes;
989 protected override void LoadExtraData (string name, XmlNode node)
991 XmlAttribute xatt = node.Attributes ["fieldtype"];
993 if (fieldTypes == null)
994 fieldTypes = new Hashtable ();
996 fieldTypes [name] = xatt.Value;
999 base.LoadExtraData (name, node);
1002 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1004 base.CompareToInner (name, parent, other);
1005 if (fieldTypes == null)
1008 XMLFields fields = (XMLFields) other;
1009 string ftype = fieldTypes [name] as string;
1010 string oftype = null;
1011 if (fields.fieldTypes != null)
1012 oftype = fields.fieldTypes [name] as string;
1014 AddWarning (parent, "Field type is {0} and should be {1}", oftype, ftype);
1017 protected override string ConvertToString (int att)
1019 FieldAttributes fa = (FieldAttributes) att;
1020 return fa.ToString ();
1023 public override string GroupName {
1024 get { return "fields"; }
1027 public override string Name {
1028 get { return "field"; }
1032 class XMLProperties : XMLMember
1034 Hashtable nameToMethod = new Hashtable ();
1036 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1038 XMLProperties oprop = other as XMLProperties;
1039 if (oprop != null) {
1040 XMLMethods m = nameToMethod [name] as XMLMethods;
1041 XMLMethods om = oprop.nameToMethod [name] as XMLMethods;
1042 if (m != null || om != null) {
1044 m = new XMLMethods ();
1046 Counters copy = counters;
1047 m.CompareTo (document, parent, om);
1048 counters = new Counters ();
1049 counters.AddPartialToPartial (m.Counters);
1050 AddCountersAttributes (parent);
1052 counters.AddPartialToPartial (m.Counters);
1056 base.CompareToInner (name, parent, other);
1059 protected override void LoadExtraData (string name, XmlNode node)
1061 XmlNode orig = node;
1062 while (node != null) {
1063 if (node != null && node.Name == "methods") {
1064 XMLMethods m = new XMLMethods ();
1065 XmlNode parent = node.ParentNode;
1066 string key = GetNodeKey (name, parent);
1068 nameToMethod [key] = m;
1071 node = node.NextSibling;
1074 base.LoadExtraData (name, orig);
1077 public override string GetNodeKey (string name, XmlNode node)
1079 XmlAttributeCollection atts = node.Attributes;
1080 return String.Format ("{0}:{1}:{2}", atts ["name"].Value,
1081 atts ["ptype"].Value,
1082 atts ["params"].Value);
1085 public override string GroupName {
1086 get { return "properties"; }
1089 public override string Name {
1090 get { return "property"; }
1094 class XMLEvents : XMLMember
1096 Hashtable eventTypes;
1098 public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
1100 base.CompareTo (doc, parent, other);
1101 AddCountersAttributes (parent);
1104 protected override void LoadExtraData (string name, XmlNode node)
1106 XmlAttribute xatt = node.Attributes ["eventtype"];
1108 if (eventTypes == null)
1109 eventTypes = new Hashtable ();
1111 eventTypes [name] = xatt.Value;
1114 base.LoadExtraData (name, node);
1117 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1119 base.CompareToInner (name, parent, other);
1120 if (eventTypes == null)
1123 XMLEvents evt = (XMLEvents) other;
1124 string etype = eventTypes [name] as string;
1125 string oetype = null;
1126 if (evt.eventTypes != null)
1127 oetype = evt.eventTypes [name] as string;
1129 AddWarning (parent, "Event type is {0} and should be {1}", oetype, etype);
1132 protected override string ConvertToString (int att)
1134 EventAttributes ea = (EventAttributes) att;
1135 return ea.ToString ();
1138 public override string GroupName {
1139 get { return "events"; }
1142 public override string Name {
1143 get { return "event"; }
1147 class XMLMethods : XMLMember
1149 Hashtable returnTypes;
1151 protected override void LoadExtraData (string name, XmlNode node)
1153 XmlAttribute xatt = node.Attributes ["returntype"];
1155 if (returnTypes == null)
1156 returnTypes = new Hashtable ();
1158 returnTypes [name] = xatt.Value;
1161 base.LoadExtraData (name, node);
1164 protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
1166 base.CompareToInner (name, parent, other);
1167 if (returnTypes == null)
1170 XMLMethods methods = (XMLMethods) other;
1171 string rtype = returnTypes [name] as string;
1172 string ortype = null;
1173 if (methods.returnTypes != null)
1174 ortype = methods.returnTypes [name] as string;
1176 AddWarning (parent, "Event type is {0} and should be {1}", ortype, rtype);
1179 protected override string ConvertToString (int att)
1181 MethodAttributes ma = (MethodAttributes) att;
1182 return ma.ToString ();
1185 public override string GroupName {
1186 get { return "methods"; }
1189 public override string Name {
1190 get { return "method"; }
1194 class XMLConstructors : XMLMethods
1196 public override string GroupName {
1197 get { return "constructors"; }
1200 public override string Name {
1201 get { return "constructor"; }
1205 class XmlNodeComparer : IComparer
1207 public static XmlNodeComparer Default = new XmlNodeComparer ();
1209 public int Compare (object a, object b)
1211 XmlNode na = (XmlNode) a;
1212 XmlNode nb = (XmlNode) b;
1213 return String.Compare (na.Attributes ["name"].Value, nb.Attributes ["name"].Value);