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