[mdoc-update-ecma-xml] Sort libraries and types.
authorJonathan Pryor <jonpryor@vt.edu>
Tue, 31 Aug 2010 18:25:01 +0000 (14:25 -0400)
committerJonathan Pryor <jonpryor@vt.edu>
Tue, 31 Aug 2010 18:51:44 +0000 (14:51 -0400)
This should help with any comparison tools as we ensure that libraries and
types are in a consistent order.

mcs/tools/mdoc/Mono.Documentation/ecmadoc.cs

index fabb9df3ea114c58acb2e38b941c5ea1d165591d..253b2b66726e76bac5fa642240523cce09cd23b3 100644 (file)
@@ -93,6 +93,9 @@ namespace Mono.Documentation
                                UpdateExistingLibraries (docs, seenLibraries);
                                GenerateMissingLibraries (docs, seenLibraries);
 
+                               SortLibraries (docs.Root);
+                               SortTypes (docs.Root);
+
                                using (var output = CreateWriter (file)) {
                                        foreach (var node in docs.Nodes ()) {
                                                if (node.NodeType == XmlNodeType.Element || node.NodeType == XmlNodeType.Text)
@@ -260,5 +263,59 @@ namespace Mono.Documentation
 
                        return type;
                }
+
+               static void SortLibraries (XContainer libraries)
+               {
+                       SortElements (libraries, (x, y) => x.Attribute ("Library").Value.CompareTo (y.Attribute ("Library").Value));
+               }
+
+               static void SortElements (XContainer container, Comparison<XElement> comparison)
+               {
+                       var items = new List<XElement> ();
+                       foreach (var e in container.Elements ())
+                               items.Add (e);
+                       items.Sort (comparison);
+                       for (int i = items.Count - 1; i > 0; --i) {
+                               items [i-1].Remove ();
+                               items [i].AddBeforeSelf (items [i-1]);
+                       }
+               }
+
+               static void SortTypes (XContainer libraries)
+               {
+                       foreach (var types in libraries.Elements ("Types")) {
+                               SortElements (types, (x, y) => {
+                                               string xName, yName;
+                                               int xCount, yCount;
+
+                                               GetTypeSortName (x, out xName, out xCount);
+                                               GetTypeSortName (y, out yName, out yCount);
+
+                                               int c = xName.CompareTo (yName);
+                                               if (c != 0)
+                                                       return c;
+                                               if (xCount < yCount)
+                                                       return -1;
+                                               if (yCount < xCount)
+                                                       return 1;
+                                               return 0;
+                               });
+                       }
+               }
+
+               static void GetTypeSortName (XElement element, out string name, out int typeParamCount)
+               {
+                       typeParamCount = 0;
+                       name = element.Attribute ("Name").Value;
+
+                       int lt = name.IndexOf ('<');
+                       if (lt >= 0) {
+                               int gt = name.IndexOf ('>', lt);
+                               if (gt >= 0) {
+                                       typeParamCount = name.Substring (lt, gt-lt).Count (c => c == ',') + 1;
+                               }
+                               name = name.Substring (0, lt);
+                       }
+               }
        }
 }