[System.Runtime.Serialization.Formatters.Soap] Make test output deterministic
[mono.git] / mcs / tools / corcompare / mono-api-html / Helpers.cs
1 // 
2 // Authors
3 //    Sebastien Pouliot  <sebastien@xamarin.com>
4 //
5 // Copyright 2013-2014 Xamarin Inc. http://www.xamarin.com
6 // 
7 // Permission is hereby granted, free of charge, to any person obtaining
8 // a copy of this software and associated documentation files (the
9 // "Software"), to deal in the Software without restriction, including
10 // without limitation the rights to use, copy, modify, merge, publish,
11 // distribute, sublicense, and/or sell copies of the Software, and to
12 // permit persons to whom the Software is furnished to do so, subject to
13 // the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be
16 // included in all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 //
26
27 using System;
28 using System.Collections.Generic;
29 using System.Linq;
30 using System.Reflection;
31 using System.Text;
32 using System.Xml.Linq;
33
34 namespace Xamarin.ApiDiff {
35
36         public static class Helper {
37                 public static bool IsTrue (this XElement self, string name)
38                 {
39                         return (self.GetAttribute (name) == "true");
40                 }
41
42                 public static string GetAttribute (this XElement self, string name)
43                 {
44                         var n = self.Attribute (name);
45                         if (n == null)
46                                 return null;
47                         return n.Value;
48                 }
49
50                 // null == no obsolete, String.Empty == no description
51                 public static string GetObsoleteMessage (this XElement self)
52                 {
53                         var cattrs = self.Element ("attributes");
54                         if (cattrs == null)
55                                 return null;
56
57                         foreach (var ca in cattrs.Elements ("attribute")) {
58                                 if (ca.GetAttribute ("name") != "System.ObsoleteAttribute")
59                                         continue;
60                                 var props = ca.Element ("properties");
61                                 if (props == null)
62                                         return String.Empty; // no description
63                                 foreach (var p in props.Elements ("property")) {
64                                         if (p.GetAttribute ("name") != "Message")
65                                                 continue;
66                                         return p.GetAttribute ("value");
67                                 }
68                         }
69                         return null;
70                 }
71
72                 public static IEnumerable<XElement> Descendants (this XElement self, params string[] names)
73                 {
74                         XElement el = self;
75                         if (el == null)
76                                 return null;
77
78                         for (int i = 0; i < names.Length - 1; i++) {
79                                 el = el.Element (names [i]);
80                                 if (el == null)
81                                         return null;
82                         }
83                         return el.Elements (names [names.Length - 1]);
84                 }
85
86                 public static List<XElement> DescendantList (this XElement self, params string[] names)
87                 {
88                         var descendants = self.Descendants (names);
89                         if (descendants == null)
90                                 return null;
91                         return descendants.ToList ();
92                 }
93
94                 // make it beautiful (.NET -> C#)
95                 public static string GetTypeName (this XElement self, string name)
96                 {
97                         string type = self.GetAttribute (name);
98                         if (type == null)
99                                 return null;
100
101                         StringBuilder sb = null;
102                         bool is_nullable = false;
103                         if (type.StartsWith ("System.Nullable`1[", StringComparison.Ordinal)) {
104                                 is_nullable = true;
105                                 sb = new StringBuilder (type, 18, type.Length - 19, 1024);
106                         } else {
107                                 sb = new StringBuilder (type);
108                         }
109
110                         bool is_ref = (sb [sb.Length - 1] == '&');
111                         if (is_ref)
112                                 sb.Remove (sb.Length - 1, 1);
113
114                         int array = 0;
115                         while ((sb [sb.Length - 1] == ']') && (sb [sb.Length - 2] == '[')) {
116                                 sb.Remove (sb.Length - 2, 2);
117                                 array++;
118                         }
119
120                         bool is_pointer = (sb [sb.Length - 1] == '*');
121                         if (is_pointer)
122                                 sb.Remove (sb.Length - 1, 1);
123
124                         type = GetTypeName (sb.Replace ('+', '.').ToString ());
125                         sb.Length = 0;
126                         if (is_ref)
127                                 sb.Append (self.GetAttribute ("direction")).Append (' ');
128
129                         sb.Append (type);
130
131                         while (array-- > 0)
132                                 sb.Append ("[]");
133                         if (is_nullable)
134                                 sb.Append ('?');
135                         if (is_pointer)
136                                 sb.Append ('*');
137                         return sb.ToString ();
138                 }
139
140                 static string GetTypeName (string type)
141                 {
142                         int pos = type.IndexOf ('`');
143                         if (pos >= 0) {
144                                 int end = type.LastIndexOf (']');
145                                 string subtype = type.Substring (pos + 3, end - pos - 3);
146                                 return type.Substring (0, pos) + "&lt;" + GetTypeName (subtype) + "&gt;";
147                         }
148
149                         switch (type) {
150                         case "System.String":
151                                 return "string";
152                         case "System.Int32":
153                                 return "int";
154                         case "System.UInt32":
155                                 return "uint";
156                         case "System.Int64":
157                                 return "long";
158                         case "System.UInt64":
159                                 return "ulong";
160                         case "System.Void":
161                                 return "void";
162                         case "System.Boolean":
163                                 return "bool";
164                         case "System.Object":
165                                 return "object";
166                         case "System.Single":
167                                 return "float";
168                         case "System.Double":
169                                 return "double";
170                         case "System.Byte":
171                                 return "byte";
172                         case "System.SByte":
173                                 return "sbyte";
174                         case "System.Int16":
175                                 return "short";
176                         case "System.UInt16":
177                                 return "ushort";
178                         case "System.Char":
179                                 return "char";
180                         case "System.nint":
181                                 return "nint";
182                         case "System.nuint":
183                                 return "uint";
184                         case "System.nfloat":
185                                 return "nfloat";
186                         case "System.IntPtr":
187                                 return "IntPtr";
188                         default:
189                                 if (type.StartsWith (State.Namespace, StringComparison.Ordinal))
190                                         type = type.Substring (State.Namespace.Length + 1);
191                                 return type;
192                         }
193                 }
194
195                 public static MethodAttributes GetMethodAttributes (this XElement element)
196                 {
197                         var srcAttribs = element.Attribute ("attrib");
198                         return (MethodAttributes) (srcAttribs != null ? Int32.Parse (srcAttribs.Value) : 0);
199                 }
200
201                 public static FieldAttributes GetFieldAttributes (this XElement element)
202                 {
203                         var srcAttribs = element.Attribute ("attrib");
204                         return (FieldAttributes) (srcAttribs != null ? Int32.Parse (srcAttribs.Value) : 0);
205                 }
206         }
207 }