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