[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Internal / TypeHelper.cs
1 // ***********************************************************************
2 // Copyright (c) 2008-2015 Charlie Poole
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
23 #define PORTABLE
24 #define TIZEN
25 #define NUNIT_FRAMEWORK
26 #define NUNITLITE
27 #define NET_4_5
28 #define PARALLEL
29 using System;
30 #if NETCF || PORTABLE
31 using System.Linq;
32 #endif
33 using System.Reflection;
34 using System.Text;
35 using NUnit.Compatibility;
36 using NUnit.Framework.Interfaces;
37
38 namespace NUnit.Framework.Internal
39 {
40     /// <summary>
41     /// TypeHelper provides static methods that operate on Types.
42     /// </summary>
43     public class TypeHelper
44     {
45         private const int STRING_MAX = 40;
46         private const int STRING_LIMIT = STRING_MAX - 3;
47         private const string THREE_DOTS = "...";
48
49         internal sealed class NonmatchingTypeClass
50         {
51         }
52
53         /// <summary>
54         /// A special value, which is used to indicate that BestCommonType() method
55         /// was unable to find a common type for the specified arguments.
56         /// </summary>
57         public static readonly Type NonmatchingType = typeof( NonmatchingTypeClass );
58
59         /// <summary>
60         /// Gets the display name for a Type as used by NUnit.
61         /// </summary>
62         /// <param name="type">The Type for which a display name is needed.</param>
63         /// <returns>The display name for the Type</returns>
64         public static string GetDisplayName(Type type)
65         {
66             if (type.IsGenericParameter)
67                 return type.Name;
68
69             if (type.GetTypeInfo().IsGenericType)
70             {
71                 string name = type.FullName;
72                 int index = name.IndexOf('[');
73                 if (index >= 0) name = name.Substring(0, index);
74
75                 index = name.LastIndexOf('.');
76                 if (index >= 0) name = name.Substring(index+1);
77
78                 var genericArguments = type.GetGenericArguments();
79                 var currentArgument = 0;
80
81                 StringBuilder sb = new StringBuilder();
82
83                 bool firstClassSeen = false;
84                 foreach (string nestedClass in name.Split('+'))
85                 {
86                     if (firstClassSeen)
87                         sb.Append("+");
88
89                     firstClassSeen = true;
90
91                     index = nestedClass.IndexOf('`');
92                     if (index >= 0)
93                     {
94                         var nestedClassName = nestedClass.Substring(0, index);
95                         sb.Append(nestedClassName);
96                         sb.Append("<");
97
98                         var argumentCount = Int32.Parse(nestedClass.Substring(index + 1));
99                         for (int i = 0; i < argumentCount; i++)
100                         {
101                             if (i > 0)
102                                 sb.Append(",");
103
104                             sb.Append(GetDisplayName(genericArguments[currentArgument++]));
105                         }
106                         sb.Append(">");
107                     }
108                     else
109                         sb.Append(nestedClass);
110                 }
111
112                 return sb.ToString();
113             }
114
115             int lastdot = type.FullName.LastIndexOf('.');
116             return lastdot >= 0 
117                 ? type.FullName.Substring(lastdot+1)
118                 : type.FullName;
119         }
120
121         /// <summary>
122         /// Gets the display name for a Type as used by NUnit.
123         /// </summary>
124         /// <param name="type">The Type for which a display name is needed.</param>
125         /// <param name="arglist">The arglist provided.</param>
126         /// <returns>The display name for the Type</returns>
127         public static string GetDisplayName(Type type, object[] arglist)
128         {
129             string baseName = GetDisplayName(type);
130             if (arglist == null || arglist.Length == 0)
131                 return baseName;
132
133             StringBuilder sb = new StringBuilder( baseName );
134
135             sb.Append("(");
136             for (int i = 0; i < arglist.Length; i++)
137             {
138                 if (i > 0) sb.Append(",");
139
140                 object arg = arglist[i];
141                 string display = arg == null ? "null" : arg.ToString();
142
143                 if (arg is double || arg is float)
144                 {
145                     if (display.IndexOf('.') == -1)
146                         display += ".0";
147                     display += arg is double ? "d" : "f";
148                 }
149                 else if (arg is decimal) display += "m";
150                 else if (arg is long) display += "L";
151                 else if (arg is ulong) display += "UL";
152                 else if (arg is string)
153                 {
154                     if (display.Length > STRING_MAX)
155                         display = display.Substring(0, STRING_LIMIT) + THREE_DOTS;
156                     display = "\"" + display + "\"";
157                 }
158
159                 sb.Append(display);
160             }
161             sb.Append(")");
162
163             return sb.ToString();
164         }
165
166         /// <summary>
167         /// Returns the best fit for a common type to be used in
168         /// matching actual arguments to a methods Type parameters.
169         /// </summary>
170         /// <param name="type1">The first type.</param>
171         /// <param name="type2">The second type.</param>
172         /// <returns>Either type1 or type2, depending on which is more general.</returns>
173         public static Type BestCommonType(Type type1, Type type2)
174         {
175             if ( type1 == TypeHelper.NonmatchingType ) return TypeHelper.NonmatchingType;
176             if ( type2 == TypeHelper.NonmatchingType ) return TypeHelper.NonmatchingType;
177
178             if (type1 == type2) return type1;
179             if (type1 == null) return type2;
180             if (type2 == null) return type1;
181
182             if (TypeHelper.IsNumeric(type1) && TypeHelper.IsNumeric(type2))
183             {
184                 if (type1 == typeof(double)) return type1;
185                 if (type2 == typeof(double)) return type2;
186
187                 if (type1 == typeof(float)) return type1;
188                 if (type2 == typeof(float)) return type2;
189
190                 if (type1 == typeof(decimal)) return type1;
191                 if (type2 == typeof(decimal)) return type2;
192
193                 if (type1 == typeof(UInt64)) return type1;
194                 if (type2 == typeof(UInt64)) return type2;
195
196                 if (type1 == typeof(Int64)) return type1;
197                 if (type2 == typeof(Int64)) return type2;
198
199                 if (type1 == typeof(UInt32)) return type1;
200                 if (type2 == typeof(UInt32)) return type2;
201
202                 if (type1 == typeof(Int32)) return type1;
203                 if (type2 == typeof(Int32)) return type2;
204
205                 if (type1 == typeof(UInt16)) return type1;
206                 if (type2 == typeof(UInt16)) return type2;
207
208                 if (type1 == typeof(Int16)) return type1;
209                 if (type2 == typeof(Int16)) return type2;
210
211                 if (type1 == typeof(byte)) return type1;
212                 if (type2 == typeof(byte)) return type2;
213
214                 if (type1 == typeof(sbyte)) return type1;
215                 if (type2 == typeof(sbyte)) return type2;
216             }
217
218             if ( type1.IsAssignableFrom( type2 ) ) return type1;
219             if ( type2.IsAssignableFrom( type1 ) ) return type2;
220
221             return TypeHelper.NonmatchingType;
222         }
223
224         /// <summary>
225         /// Determines whether the specified type is numeric.
226         /// </summary>
227         /// <param name="type">The type to be examined.</param>
228         /// <returns>
229         ///     <c>true</c> if the specified type is numeric; otherwise, <c>false</c>.
230         /// </returns>
231         public static bool IsNumeric(Type type)
232         {
233             return type == typeof(double) ||
234                     type == typeof(float) ||
235                     type == typeof(decimal) ||
236                     type == typeof(Int64) ||
237                     type == typeof(Int32) ||
238                     type == typeof(Int16) ||
239                     type == typeof(UInt64) ||
240                     type == typeof(UInt32) ||
241                     type == typeof(UInt16) ||
242                     type == typeof(byte) ||
243                     type == typeof(sbyte);
244         }
245
246         /// <summary>
247         /// Convert an argument list to the required parameter types.
248         /// Currently, only widening numeric conversions are performed.
249         /// </summary>
250         /// <param name="arglist">An array of args to be converted</param>
251         /// <param name="parameters">A ParameterInfo[] whose types will be used as targets</param>
252         public static void ConvertArgumentList(object[] arglist, IParameterInfo[] parameters)
253         {
254             System.Diagnostics.Debug.Assert(arglist.Length <= parameters.Length);
255
256             for (int i = 0; i < arglist.Length; i++)
257             {
258                 object arg = arglist[i];
259
260 #if PORTABLE
261                 if (arg != null)
262 #else
263                 if (arg != null && arg is IConvertible)
264 #endif
265                 {
266                     Type argType = arg.GetType();
267                     Type targetType = parameters[i].ParameterType;
268                     bool convert = false;
269
270                     if (argType != targetType && !argType.IsAssignableFrom(targetType))
271                     {
272                         if (IsNumeric(argType) && IsNumeric(targetType))
273                         {
274                             if (targetType == typeof(double) || targetType == typeof(float))
275                                 convert = arg is int || arg is long || arg is short || arg is byte || arg is sbyte;
276                             else
277                                 if (targetType == typeof(long))
278                                     convert = arg is int || arg is short || arg is byte || arg is sbyte;
279                                 else
280                                     if (targetType == typeof(short))
281                                         convert = arg is byte || arg is sbyte;
282                         }
283                     }
284
285                     if (convert)
286                         arglist[i] = Convert.ChangeType(arg, targetType,
287                             System.Globalization.CultureInfo.InvariantCulture);
288                 }
289             }
290         }
291
292         /// <summary>
293         /// Determines whether this instance can deduce type args for a generic type from the supplied arguments.
294         /// </summary>
295         /// <param name="type">The type to be examined.</param>
296         /// <param name="arglist">The arglist.</param>
297         /// <param name="typeArgsOut">The type args to be used.</param>
298         /// <returns>
299         ///     <c>true</c> if this the provided args give sufficient information to determine the type args to be used; otherwise, <c>false</c>.
300         /// </returns>
301         public static bool CanDeduceTypeArgsFromArgs(Type type, object[] arglist, ref Type[] typeArgsOut)
302         {
303             Type[] typeParameters = type.GetGenericArguments();
304
305 #if NETCF || PORTABLE
306             Type[] argTypes = arglist.Select(a => a == null ? typeof(object) : a.GetType()).ToArray();
307             if (argTypes.Length != typeParameters.Length || argTypes.Any(at => at.GetTypeInfo().IsGenericType))
308                 return false;
309             try
310             {
311                 type = type.MakeGenericType(argTypes);
312             }
313             catch (Exception)
314             {
315                 return false;
316             }
317 #endif
318
319             foreach (ConstructorInfo ctor in type.GetConstructors())
320             {
321                 ParameterInfo[] parameters = ctor.GetParameters();
322                 if (parameters.Length != arglist.Length)
323                     continue;
324
325                 Type[] typeArgs = new Type[typeParameters.Length];
326                 for (int i = 0; i < typeArgs.Length; i++)
327                 {
328                     for (int j = 0; j < arglist.Length; j++)
329                     {
330                         if (typeParameters[i].IsGenericParameter || parameters[j].ParameterType.Equals(typeParameters[i]))
331                             typeArgs[i] = TypeHelper.BestCommonType(
332                                               typeArgs[i],
333                                               arglist[j].GetType());
334                     }
335
336                     if (typeArgs[i] == null)
337                     {
338                         typeArgs = null;
339                         break;
340                     }
341                 }
342
343                 if (typeArgs != null)
344                 {
345                     typeArgsOut = typeArgs;
346                     return true;
347                 }
348             }
349
350             return false;
351         }
352
353         /// <summary>
354         /// Gets the _values for an enumeration, using Enum.GetTypes
355         /// where available, otherwise through reflection.
356         /// </summary>
357         /// <param name="enumType"></param>
358         /// <returns></returns>
359         public static Array GetEnumValues(Type enumType)
360         {
361 #if NETCF || SILVERLIGHT
362             FieldInfo[] fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
363
364             Array enumValues = Array.CreateInstance(enumType, fields.Length);
365
366             for (int index = 0; index < fields.Length; index++)
367                 enumValues.SetValue(fields[index].GetValue(enumType), index);
368
369             return enumValues;
370 #else
371             return Enum.GetValues(enumType);
372 #endif
373         }
374
375         /// <summary>
376         /// Gets the ids of the _values for an enumeration, 
377         /// using Enum.GetNames where available, otherwise
378         /// through reflection.
379         /// </summary>
380         /// <param name="enumType"></param>
381         /// <returns></returns>
382         public static string[] GetEnumNames(Type enumType)
383         {
384 #if NETCF || SILVERLIGHT
385             FieldInfo[] fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
386
387             string[] names = new string[fields.Length];
388
389             for (int index = 0; index < fields.Length; index++)
390                 names[index] =  fields[index].Name;
391
392             return names;
393 #else
394             return Enum.GetNames(enumType);
395 #endif
396         }
397     }
398 }