Fix to UriTemplate.Match to properly handle query parameters without a value. No...
[mono.git] / mcs / class / corlib / System / MonoType.cs
1 //
2 // System.MonoType
3 //
4 // Authors: 
5 //      Sean MacIsaac (macisaac@ximian.com)
6 //      Paolo Molaro (lupus@ximian.com)
7 //      Patrik Torstensson (patrik.torstensson@labs2.com)
8 //      Gonzalo Paniagua (gonzalo@ximian.com)
9 //  Marek Safar (marek.safar@gmail.com)
10 //
11 // (c) 2001-2003 Ximian, Inc.
12 // Copyright (C) 2003-2005 Novell, Inc (http://www.novell.com)
13 // Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System.Collections.Generic;
36 using System.Globalization;
37 using System.Reflection;
38 using System.Runtime.InteropServices;
39 using System.Runtime.CompilerServices;
40 using System.Runtime.Serialization;
41 using System.Security;
42
43 namespace System
44 {
45         // Contains information about the type which is expensive to compute
46         [StructLayout (LayoutKind.Sequential)]
47         internal class MonoTypeInfo {
48                 public string full_name;
49                 public MonoCMethod default_ctor;
50         }
51                 
52         abstract class RuntimeType : TypeInfo
53         {
54
55         }
56
57         [Serializable]
58         [StructLayout (LayoutKind.Sequential)]
59         sealed class MonoType : RuntimeType, ISerializable
60         {
61                 [NonSerialized]
62                 MonoTypeInfo type_info;
63
64                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
65                 private static extern void type_from_obj (MonoType type, Object obj);
66                 
67                 internal MonoType (Object obj)
68                 {
69                         // this should not be used - lupus
70                         type_from_obj (this, obj);
71                         
72                         throw new NotImplementedException ();
73                 }
74
75                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
76                 private static extern TypeAttributes get_attributes (Type type);
77
78                 public MonoCMethod GetDefaultConstructor ()
79                 {
80                         MonoCMethod ctor = null;
81                         
82                         if (type_info == null)
83                                 type_info = new MonoTypeInfo ();
84                         else
85                                 ctor = type_info.default_ctor;
86
87                         if (ctor == null) {
88                                 var ctors = GetConstructors (BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
89
90                                 for (int i = 0; i < ctors.Length; ++i) {
91                                         if (ctors [i].GetParametersCount () == 0) {
92                                                 type_info.default_ctor = ctor = (MonoCMethod) ctors [i];
93                                                 break;
94                                         }
95                                 }
96                         }
97
98                         return ctor;
99                 }
100
101                 protected override TypeAttributes GetAttributeFlagsImpl ()
102                 {
103                         return get_attributes (this);
104                 }
105
106                 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
107                                                                        Binder binder,
108                                                                        CallingConventions callConvention,
109                                                                        Type[] types,
110                                                                        ParameterModifier[] modifiers)
111                 {
112                         ConstructorInfo[] methods = GetConstructors (bindingAttr);
113                         return GetConstructorImpl (methods, bindingAttr, binder, callConvention, types, modifiers);
114                 }
115
116                 internal static ConstructorInfo GetConstructorImpl (ConstructorInfo[] methods, BindingFlags bindingAttr,
117                                                                        Binder binder,
118                                                                        CallingConventions callConvention,
119                                                                        Type[] types,
120                                                                        ParameterModifier[] modifiers)
121                 {
122                         if (bindingAttr == BindingFlags.Default)
123                                 bindingAttr = BindingFlags.Public | BindingFlags.Instance;
124
125                         ConstructorInfo found = null;
126                         MethodBase[] match;
127                         int count = 0;
128                         foreach (ConstructorInfo m in methods) {
129                                 // Under MS.NET, Standard|HasThis matches Standard...
130                                 if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
131                                         continue;
132                                 found = m;
133                                 count++;
134                         }
135                         if (count == 0)
136                                 return null;
137                         if (types == null) {
138                                 if (count > 1)
139                                         throw new AmbiguousMatchException ();
140                                 return (ConstructorInfo) CheckMethodSecurity (found);
141                         }
142                         match = new MethodBase [count];
143                         if (count == 1)
144                                 match [0] = found;
145                         else {
146                                 count = 0;
147                                 foreach (ConstructorInfo m in methods) {
148                                         if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
149                                                 continue;
150                                         match [count++] = m;
151                                 }
152                         }
153                         if (binder == null)
154                                 binder = Binder.DefaultBinder;
155                         return (ConstructorInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, match, types, modifiers));
156                 }
157
158                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
159                 internal extern ConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, Type reflected_type);
160
161                 public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
162                 {
163                         return GetConstructors_internal (bindingAttr, this);
164                 }
165
166                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
167                 extern EventInfo InternalGetEvent (string name, BindingFlags bindingAttr);
168
169                 public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
170                 {
171                         if (name == null)
172                                 throw new ArgumentNullException ("name");
173
174                         return InternalGetEvent (name, bindingAttr);
175                 }
176
177                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
178                 internal extern EventInfo[] GetEvents_internal (BindingFlags bindingAttr, Type reflected_type);
179
180                 public override EventInfo[] GetEvents (BindingFlags bindingAttr)
181                 {
182                         return GetEvents_internal (bindingAttr, this);
183                 }
184
185                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
186                 public extern override FieldInfo GetField (string name, BindingFlags bindingAttr);
187
188                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
189                 internal extern FieldInfo[] GetFields_internal (BindingFlags bindingAttr, Type reflected_type);
190
191                 public override FieldInfo[] GetFields (BindingFlags bindingAttr)
192                 {
193                         return GetFields_internal (bindingAttr, this);
194                 }
195                 
196                 public override Type GetInterface (string name, bool ignoreCase)
197                 {
198                         if (name == null)
199                                 throw new ArgumentNullException ();
200
201                         Type[] interfaces = GetInterfaces();
202
203                         foreach (Type type in interfaces) {
204                                 /*We must compare against the generic type definition*/
205                                 Type t = type.IsGenericType ? type.GetGenericTypeDefinition () : type;
206
207                                 if (String.Compare (t.Name, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
208                                         return type;
209                                 if (String.Compare (t.FullName, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
210                                         return type;
211                         }
212
213                         return null;
214                 }
215
216                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
217                 public extern override Type[] GetInterfaces();
218
219                 public override InterfaceMapping GetInterfaceMap (Type interfaceType)
220                 {
221                         if (!IsSystemType)
222                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
223                         if (interfaceType == null)
224                                 throw new ArgumentNullException ("interfaceType");
225                         if (!interfaceType.IsSystemType)
226                                 throw new ArgumentException ("interfaceType", "Type is an user type");
227                         InterfaceMapping res;
228                         if (!interfaceType.IsInterface)
229                                 throw new ArgumentException (Locale.GetText ("Argument must be an interface."), "interfaceType");
230                         if (IsInterface)
231                                 throw new ArgumentException ("'this' type cannot be an interface itself");
232                         res.TargetType = this;
233                         res.InterfaceType = interfaceType;
234                         GetInterfaceMapData (this, interfaceType, out res.TargetMethods, out res.InterfaceMethods);
235                         if (res.TargetMethods == null)
236                                 throw new ArgumentException (Locale.GetText ("Interface not found"), "interfaceType");
237
238                         return res;
239                 }
240                 
241                 public override MemberInfo[] GetMembers( BindingFlags bindingAttr)
242                 {
243                         return FindMembers (MemberTypes.All, bindingAttr, null, null);
244                 }
245
246                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
247                 internal extern MethodInfo [] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type);
248
249                 public override MethodInfo [] GetMethods (BindingFlags bindingAttr)
250                 {
251                         return GetMethodsByName (null, bindingAttr, false, this);
252                 }
253
254                 protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr,
255                                                              Binder binder,
256                                                              CallingConventions callConvention,
257                                                              Type[] types, ParameterModifier[] modifiers)
258                 {
259                         bool ignoreCase = ((bindingAttr & BindingFlags.IgnoreCase) != 0);
260                         MethodInfo[] methods = GetMethodsByName (name, bindingAttr, ignoreCase, this);
261                         MethodInfo found = null;
262                         MethodBase[] match;
263                         int count = 0;
264                         
265                         foreach (MethodInfo m in methods) {
266                                 // Under MS.NET, Standard|HasThis matches Standard...
267                                 if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
268                                         continue;
269                                 found = m;
270                                 count++;
271                         }
272
273                         if (count == 0)
274                                 return null;
275                         
276                         if (count == 1 && types == null) 
277                                 return (MethodInfo) CheckMethodSecurity (found);
278
279                         match = new MethodBase [count];
280                         if (count == 1)
281                                 match [0] = found;
282                         else {
283                                 count = 0;
284                                 foreach (MethodInfo m in methods) {
285                                         if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
286                                                 continue;
287                                         match [count++] = m;
288                                 }
289                         }
290
291                         if (types == null) 
292                                 return (MethodInfo) CheckMethodSecurity (Binder.FindMostDerivedMatch (match));
293
294                         if (binder == null)
295                                 binder = Binder.DefaultBinder;
296                         
297                         return (MethodInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, match, types, modifiers));
298                 }
299
300                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
301                 extern MethodInfo GetCorrespondingInflatedMethod (MethodInfo generic);
302
303                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
304                 extern ConstructorInfo GetCorrespondingInflatedConstructor (ConstructorInfo generic);
305
306                 internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
307                 {
308                         if (fromNoninstanciated == null)
309                                 throw new ArgumentNullException ("fromNoninstanciated");
310                         return GetCorrespondingInflatedMethod (fromNoninstanciated);
311                 }
312
313                 internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
314                 {
315                         if (fromNoninstanciated == null)
316                                 throw new ArgumentNullException ("fromNoninstanciated");
317                         return GetCorrespondingInflatedConstructor (fromNoninstanciated);
318                 }
319
320                 internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
321                 {
322                         /* create sensible flags from given FieldInfo */
323                         BindingFlags flags = fromNoninstanciated.IsStatic ? BindingFlags.Static : BindingFlags.Instance;
324                         flags |= fromNoninstanciated.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic;
325                         return GetField (fromNoninstanciated.Name, flags);
326                 }
327
328                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
329                 public extern override Type GetNestedType (string name, BindingFlags bindingAttr);
330
331                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
332                 public extern override Type[] GetNestedTypes (BindingFlags bindingAttr);
333
334                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
335                 internal extern PropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, Type reflected_type);
336
337                 public override PropertyInfo [] GetProperties (BindingFlags bindingAttr)
338                 {
339                         return GetPropertiesByName (null, bindingAttr, false, this);
340                 }
341
342                 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr,
343                                                                  Binder binder, Type returnType,
344                                                                  Type[] types,
345                                                                  ParameterModifier[] modifiers)
346                 {
347                         bool ignoreCase = ((bindingAttr & BindingFlags.IgnoreCase) != 0);
348                         PropertyInfo [] props = GetPropertiesByName (name, bindingAttr, ignoreCase, this);
349                         int count = props.Length;
350                         if (count == 0)
351                                 return null;
352                         
353                         if (count == 1 && (types == null || types.Length == 0) && 
354                             (returnType == null || returnType == props[0].PropertyType))
355                                 return props [0];
356
357                         if (binder == null)
358                                 binder = Binder.DefaultBinder;
359
360                         return binder.SelectProperty (bindingAttr, props, returnType, types, modifiers);
361                 }
362
363                 protected override bool HasElementTypeImpl ()
364                 {
365                         return IsArrayImpl() || IsByRefImpl() || IsPointerImpl ();
366                 }
367
368                 protected override bool IsArrayImpl ()
369                 {
370                         return Type.IsArrayImpl (this);
371                 }
372
373                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
374                 protected extern override bool IsByRefImpl ();
375
376                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
377                 protected extern override bool IsCOMObjectImpl ();
378
379                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
380                 protected extern override bool IsPointerImpl ();
381
382                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
383                 protected extern override bool IsPrimitiveImpl ();
384
385                 public override bool IsSubclassOf (Type type)
386                 {
387                         if (type == null)
388                                 throw new ArgumentNullException ("type");
389
390                         return base.IsSubclassOf (type);
391                 }
392
393                 public override object InvokeMember (string name, BindingFlags invokeAttr,
394                                                      Binder binder, object target, object[] args,
395                                                      ParameterModifier[] modifiers,
396                                                      CultureInfo culture, string[] namedParameters)
397                 {
398                         const string bindingflags_arg = "bindingFlags";
399
400
401                         if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
402                                 if ((invokeAttr & (BindingFlags.GetField |
403                                                 BindingFlags.GetField | BindingFlags.GetProperty |
404                                                 BindingFlags.SetProperty)) != 0)
405                                         throw new ArgumentException (bindingflags_arg);
406                         } else if (name == null)
407                                 throw new ArgumentNullException ("name");
408                         if ((invokeAttr & BindingFlags.GetField) != 0 && (invokeAttr & BindingFlags.SetField) != 0)
409                                 throw new ArgumentException ("Cannot specify both Get and Set on a field.", bindingflags_arg);
410                         if ((invokeAttr & BindingFlags.GetProperty) != 0 && (invokeAttr & BindingFlags.SetProperty) != 0)
411                                 throw new ArgumentException ("Cannot specify both Get and Set on a property.", bindingflags_arg);
412                         if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
413                                 if ((invokeAttr & BindingFlags.SetField) != 0)
414                                         throw new ArgumentException ("Cannot specify Set on a field and Invoke on a method.", bindingflags_arg);
415                                 if ((invokeAttr & BindingFlags.SetProperty) != 0)
416                                         throw new ArgumentException ("Cannot specify Set on a property and Invoke on a method.", bindingflags_arg);
417                         }
418                         if ((namedParameters != null) && ((args == null) || args.Length < namedParameters.Length))
419                                 throw new ArgumentException ("namedParameters cannot be more than named arguments in number");
420                         if ((invokeAttr & (BindingFlags.InvokeMethod|BindingFlags.CreateInstance|BindingFlags.GetField|BindingFlags.SetField|BindingFlags.GetProperty|BindingFlags.SetProperty)) == 0)
421                                 throw new ArgumentException ("Must specify binding flags describing the invoke operation required.", bindingflags_arg);
422
423                         /* set some defaults if none are provided :-( */
424                         if ((invokeAttr & (BindingFlags.Public|BindingFlags.NonPublic)) == 0)
425                                 invokeAttr |= BindingFlags.Public;
426                         if ((invokeAttr & (BindingFlags.Static|BindingFlags.Instance)) == 0)
427                                 invokeAttr |= BindingFlags.Static|BindingFlags.Instance;
428
429                         if (binder == null)
430                                 binder = DefaultBinder;
431
432                         if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
433                                 return Activator.CreateInstance (this, invokeAttr, binder, args, culture);
434                         }
435                         if (name == String.Empty && Attribute.IsDefined (this, typeof (DefaultMemberAttribute))) {
436                                 DefaultMemberAttribute attr = (DefaultMemberAttribute) Attribute.GetCustomAttribute (this, typeof (DefaultMemberAttribute));
437                                 name = attr.MemberName;
438                         }
439                         bool ignoreCase = (invokeAttr & BindingFlags.IgnoreCase) != 0;
440                         string throwMissingMethodDescription = null;
441                         bool throwMissingFieldException = false;
442                         
443                         if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
444                                 MethodInfo[] methods = GetMethodsByName (name, invokeAttr, ignoreCase, this);
445                                 object state = null;
446                                 if (args == null)
447                                         args = EmptyArray<object>.Value;
448                                 MethodBase m = binder.BindToMethod (invokeAttr, methods, ref args, modifiers, culture, namedParameters, out state);
449                                 if (m == null) {
450                                         if (methods.Length > 0)
451                                                 throwMissingMethodDescription = "The best match for method " + name + " has some invalid parameter.";
452                                         else
453                                                 throwMissingMethodDescription = "Cannot find method " + name + ".";
454                                 } else {
455                                         ParameterInfo[] parameters = m.GetParametersInternal();
456                                         for (int i = 0; i < parameters.Length; ++i) {
457                                                 if (System.Reflection.Missing.Value == args [i] && (parameters [i].Attributes & ParameterAttributes.HasDefault) != ParameterAttributes.HasDefault)
458                                                         throw new ArgumentException ("Used Missing.Value for argument without default value", "parameters");
459                                         }
460                                         object result = m.Invoke (target, invokeAttr, binder, args, culture);
461                                         binder.ReorderArgumentArray (ref args, state);
462                                         return result;
463                                 }
464                         }
465                         if ((invokeAttr & BindingFlags.GetField) != 0) {
466                                 FieldInfo f = GetField (name, invokeAttr);
467                                 if (f != null) {
468                                         return f.GetValue (target);
469                                 } else if ((invokeAttr & BindingFlags.GetProperty) == 0) {
470                                         throwMissingFieldException = true;
471                                 }
472                                 /* try GetProperty */
473                         } else if ((invokeAttr & BindingFlags.SetField) != 0) {
474                                 FieldInfo f = GetField (name, invokeAttr);
475                                 if (f != null) {
476                                         if (args == null)
477                                                 throw new ArgumentNullException ("providedArgs");
478                                         if ((args == null) || args.Length != 1)
479                                                 throw new ArgumentException ("Only the field value can be specified to set a field value.", bindingflags_arg);
480                                         f.SetValue (target, args [0]);
481                                         return null;
482                                 } else if ((invokeAttr & BindingFlags.SetProperty) == 0) {
483                                         throwMissingFieldException = true;
484                                 }
485                                 /* try SetProperty */
486                         }
487                         if ((invokeAttr & BindingFlags.GetProperty) != 0) {
488                                 PropertyInfo[] properties = GetPropertiesByName (name, invokeAttr, ignoreCase, this);
489                                 object state = null;
490                                 int i, count = 0;
491                                 for (i = 0; i < properties.Length; ++i) {
492                                         if ((properties [i].GetGetMethod (true) != null))
493                                                 count++;
494                                 }
495                                 MethodBase[] smethods = new MethodBase [count];
496                                 count = 0;
497                                 for (i = 0; i < properties.Length; ++i) {
498                                         MethodBase mb = properties [i].GetGetMethod (true);
499                                         if (mb != null)
500                                                 smethods [count++] = mb;
501                                 }
502                                 MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, out state);
503                                 if (m == null) {
504                                         throwMissingFieldException = true;
505                                 } else {
506                                         object result = m.Invoke (target, invokeAttr, binder, args, culture);
507                                         binder.ReorderArgumentArray (ref args, state);
508                                         return result;
509                                 }
510                         } else if ((invokeAttr & BindingFlags.SetProperty) != 0) {
511                                 PropertyInfo[] properties = GetPropertiesByName (name, invokeAttr, ignoreCase, this);
512                                 object state = null;
513                                 int i, count = 0;
514                                 for (i = 0; i < properties.Length; ++i) {
515                                         if (properties [i].GetSetMethod (true) != null)
516                                                 count++;
517                                 }
518                                 MethodBase[] smethods = new MethodBase [count];
519                                 count = 0;
520                                 for (i = 0; i < properties.Length; ++i) {
521                                         MethodBase mb = properties [i].GetSetMethod (true);
522                                         if (mb != null)
523                                                 smethods [count++] = mb;
524                                 }
525                                 MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, out state);
526                                 if (m == null) {
527                                         throwMissingFieldException = true;
528                                 } else {
529                                         object result = m.Invoke (target, invokeAttr, binder, args, culture);
530                                         binder.ReorderArgumentArray (ref args, state);
531                                         return result;
532                                 }
533                         }
534                         if (throwMissingMethodDescription != null)
535                                 throw new MissingMethodException(throwMissingMethodDescription);
536                         if (throwMissingFieldException)
537                                 throw new MissingFieldException("Cannot find variable " + name + ".");
538
539                         return null;
540                 }
541
542                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
543                 public extern override Type GetElementType ();
544
545                 public override Type UnderlyingSystemType {
546                         get {
547                                 // This has _nothing_ to do with getting the base type of an enum etc.
548                                 return this;
549                         }
550                 }
551
552                 public extern override Assembly Assembly {
553                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
554                         get;
555                 }
556
557                 public override string AssemblyQualifiedName {
558                         get {
559                                 return getFullName (true, true);
560                         }
561                 }
562
563                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
564                 private extern string getFullName(bool full_name, bool assembly_qualified);
565
566                 public extern override Type BaseType {
567                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
568                         get;
569                 }
570
571                 public override string FullName {
572                         get {
573                                 string fullName;
574                                 // This doesn't need locking
575                                 if (type_info == null)
576                                         type_info = new MonoTypeInfo ();
577                                 if ((fullName = type_info.full_name) == null)
578                                         fullName = type_info.full_name = getFullName (true, false);
579
580                                 return fullName;
581                         }
582                 }
583
584                 public override Guid GUID {
585                         get {
586                                 object[] att = GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), true);
587                                 if (att.Length == 0)
588                                         return Guid.Empty;
589                                 return new Guid(((System.Runtime.InteropServices.GuidAttribute)att[0]).Value);
590                         }
591                 }
592
593                 public override bool IsDefined (Type attributeType, bool inherit)
594                 {
595                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
596                 }
597
598                 public override object[] GetCustomAttributes (bool inherit)
599                 {
600                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
601                 }
602
603                 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
604                 {
605                         if (attributeType == null)
606                         {
607                                 throw new ArgumentNullException("attributeType");
608                         }
609                         
610                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
611                 }
612
613                 public override MemberTypes MemberType {
614                         get {
615                                 if (DeclaringType != null && !IsGenericParameter)
616                                         return MemberTypes.NestedType;
617                                 else
618                                         return MemberTypes.TypeInfo;
619                         }
620                 }
621
622                 public extern override string Name {
623                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
624                         get;
625                 }
626
627                 public extern override string Namespace {
628                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
629                         get;
630                 }
631
632                 public extern override Module Module {
633                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
634                         get;
635                 }
636
637                 public extern override Type DeclaringType {
638                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
639                         get;
640                 }
641
642                 public override Type ReflectedType {
643                         get {
644                                 return DeclaringType;
645                         }
646                 }
647
648                 public override RuntimeTypeHandle TypeHandle {
649                         get {
650                                 return _impl;
651                         }
652                 }
653
654                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
655                 public extern override int GetArrayRank ();
656
657                 public void GetObjectData(SerializationInfo info, StreamingContext context)
658                 {
659                         UnitySerializationHolder.GetTypeData (this, info, context);
660                 }
661
662                 public override string ToString()
663                 {
664                         return getFullName (false, false);
665                 }
666
667                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
668                 public extern override Type [] GetGenericArguments ();
669
670                 public override bool ContainsGenericParameters {
671                         get {
672                                 if (IsGenericParameter)
673                                         return true;
674
675                                 if (IsGenericType) {
676                                         foreach (Type arg in GetGenericArguments ())
677                                                 if (arg.ContainsGenericParameters)
678                                                         return true;
679                                 }
680
681                                 if (HasElementType)
682                                         return GetElementType ().ContainsGenericParameters;
683
684                                 return false;
685                         }
686                 }
687
688                 public extern override bool IsGenericParameter {
689                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
690                         get;
691                 }
692
693                 public extern override MethodBase DeclaringMethod {
694                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
695                         get;
696                 }
697
698                 public override Type GetGenericTypeDefinition () {
699                         Type res = GetGenericTypeDefinition_impl ();
700                         if (res == null)
701                                 throw new InvalidOperationException ();
702
703                         return res;
704                 }
705
706                 public override IList<CustomAttributeData> GetCustomAttributesData () {
707                         return CustomAttributeData.GetCustomAttributes (this);
708                 }
709
710
711                 public override Array GetEnumValues () {
712                         if (!IsEnum)
713                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
714
715                         return Enum.GetValues (this);
716                 }
717
718                 static MethodBase CheckMethodSecurity (MethodBase mb)
719                 {
720 #if NET_2_1
721                         return mb;
722 #else
723                         if (!SecurityManager.SecurityEnabled || (mb == null))
724                                 return mb;
725
726                         // Sadly we have no way to know which kind of security action this is
727                         // so we must do it the hard way. Actually this isn't so bad 
728                         // because we can skip the (mb.Attributes & MethodAttributes.HasSecurity)
729                         // icall required (and do it ourselves)
730
731                         // this (unlike the Invoke step) is _and stays_ a LinkDemand (caller)
732                         return SecurityManager.ReflectedLinkDemandQuery (mb) ? mb : null;
733 #endif
734                 }
735
736                 //seclevel { transparent = 0, safe-critical = 1, critical = 2}
737                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
738                 public extern int get_core_clr_security_level ();
739
740                 public override bool IsSecurityTransparent
741                 {
742                         get { return get_core_clr_security_level () == 0; }
743                 }
744
745                 public override bool IsSecurityCritical
746                 {
747                         get { return get_core_clr_security_level () > 0; }
748                 }
749
750                 public override bool IsSecuritySafeCritical
751                 {
752                         get { return get_core_clr_security_level () == 1; }
753                 }
754
755                 public override StructLayoutAttribute StructLayoutAttribute {
756                         get {
757                                 return GetStructLayoutAttribute ();
758                         }
759                 }
760
761                 internal override bool IsUserType {
762                         get {
763                                 return false;
764                         }
765                 }
766
767                 public override bool IsConstructedGenericType {
768                         get {
769                                 return IsGenericType && !ContainsGenericParameters;
770                         }
771                 }
772         }
773 }