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)
10 // (c) 2001-2003 Ximian, Inc.
11 // Copyright (C) 2003-2005 Novell, Inc (http://www.novell.com)
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:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
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.
33 using System.Globalization;
34 using System.Reflection;
35 using System.Runtime.CompilerServices;
36 using System.Runtime.Serialization;
37 using System.Security;
42 internal class MonoType : Type, ISerializable
45 [MethodImplAttribute(MethodImplOptions.InternalCall)]
46 private static extern void type_from_obj (MonoType type, Object obj);
49 internal MonoType (Object obj)
51 // this should not be used - lupus
52 type_from_obj (this, obj);
54 throw new NotImplementedException ();
57 [MethodImplAttribute(MethodImplOptions.InternalCall)]
58 private static extern TypeAttributes get_attributes (Type type);
60 protected override TypeAttributes GetAttributeFlagsImpl ()
62 return get_attributes (this);
65 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
67 CallingConventions callConvention,
69 ParameterModifier[] modifiers)
71 if (bindingAttr == BindingFlags.Default)
72 bindingAttr = BindingFlags.Public | BindingFlags.Instance;
74 ConstructorInfo[] methods = GetConstructors (bindingAttr);
75 ConstructorInfo found = null;
78 foreach (ConstructorInfo m in methods) {
79 // Under MS.NET, Standard|HasThis matches Standard...
80 if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
89 throw new AmbiguousMatchException ();
90 return (ConstructorInfo) CheckMethodSecurity (found);
92 match = new MethodBase [count];
97 foreach (ConstructorInfo m in methods) {
98 if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
104 binder = Binder.DefaultBinder;
105 return (ConstructorInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, match, types, modifiers));
108 [MethodImplAttribute(MethodImplOptions.InternalCall)]
109 internal extern ConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, Type reflected_type);
111 public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
113 return GetConstructors_internal (bindingAttr, this);
116 [MethodImplAttribute(MethodImplOptions.InternalCall)]
117 extern EventInfo InternalGetEvent (string name, BindingFlags bindingAttr);
119 public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
122 throw new ArgumentNullException ("name");
124 return InternalGetEvent (name, bindingAttr);
127 [MethodImplAttribute(MethodImplOptions.InternalCall)]
128 internal extern EventInfo[] GetEvents_internal (BindingFlags bindingAttr, Type reflected_type);
130 public override EventInfo[] GetEvents (BindingFlags bindingAttr)
132 return GetEvents_internal (bindingAttr, this);
135 [MethodImplAttribute(MethodImplOptions.InternalCall)]
136 public extern override FieldInfo GetField (string name, BindingFlags bindingAttr);
138 [MethodImplAttribute(MethodImplOptions.InternalCall)]
139 internal extern FieldInfo[] GetFields_internal (BindingFlags bindingAttr, Type reflected_type);
141 public override FieldInfo[] GetFields (BindingFlags bindingAttr)
143 return GetFields_internal (bindingAttr, this);
146 public override Type GetInterface (string name, bool ignoreCase)
149 throw new ArgumentNullException ();
151 Type[] interfaces = GetInterfaces();
153 foreach (Type type in interfaces) {
154 if (String.Compare (type.Name, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
156 if (String.Compare (type.FullName, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
163 [MethodImplAttribute(MethodImplOptions.InternalCall)]
164 public extern override Type[] GetInterfaces();
166 public override MemberInfo[] GetMembers( BindingFlags bindingAttr)
168 return FindMembers (MemberTypes.All, bindingAttr, null, null);
171 [MethodImplAttribute(MethodImplOptions.InternalCall)]
172 internal extern MethodInfo [] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type);
174 public override MethodInfo [] GetMethods (BindingFlags bindingAttr)
176 return GetMethodsByName (null, bindingAttr, false, this);
179 protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr,
181 CallingConventions callConvention,
182 Type[] types, ParameterModifier[] modifiers)
184 bool ignoreCase = ((bindingAttr & BindingFlags.IgnoreCase) != 0);
185 MethodInfo[] methods = GetMethodsByName (name, bindingAttr, ignoreCase, this);
186 MethodInfo found = null;
190 foreach (MethodInfo m in methods) {
191 // Under MS.NET, Standard|HasThis matches Standard...
192 if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
201 if (count == 1 && types == null)
202 return (MethodInfo) CheckMethodSecurity (found);
204 match = new MethodBase [count];
209 foreach (MethodInfo m in methods) {
210 if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
217 return (MethodInfo) CheckMethodSecurity (Binder.FindMostDerivedMatch (match));
220 binder = Binder.DefaultBinder;
222 return (MethodInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, match, types, modifiers));
225 [MethodImplAttribute(MethodImplOptions.InternalCall)]
226 extern MethodInfo GetCorrespondingInflatedMethod (MethodInfo generic);
228 [MethodImplAttribute(MethodImplOptions.InternalCall)]
229 extern ConstructorInfo GetCorrespondingInflatedConstructor (ConstructorInfo generic);
231 internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
233 return GetCorrespondingInflatedMethod (fromNoninstanciated);
236 internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
238 return GetCorrespondingInflatedConstructor (fromNoninstanciated);
241 internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
243 return GetField (fromNoninstanciated.Name);
246 [MethodImplAttribute(MethodImplOptions.InternalCall)]
247 public extern override Type GetNestedType (string name, BindingFlags bindingAttr);
249 [MethodImplAttribute(MethodImplOptions.InternalCall)]
250 public extern override Type[] GetNestedTypes (BindingFlags bindingAttr);
252 [MethodImplAttribute(MethodImplOptions.InternalCall)]
253 internal extern PropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, Type reflected_type);
255 public override PropertyInfo [] GetProperties (BindingFlags bindingAttr)
257 return GetPropertiesByName (null, bindingAttr, false, this);
260 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr,
261 Binder binder, Type returnType,
263 ParameterModifier[] modifiers)
265 bool ignoreCase = ((bindingAttr & BindingFlags.IgnoreCase) != 0);
266 PropertyInfo [] props = GetPropertiesByName (name, bindingAttr, ignoreCase, this);
267 int count = props.Length;
271 if (count == 1 && (types == null || types.Length == 0))
275 binder = Binder.DefaultBinder;
277 return binder.SelectProperty (bindingAttr, props, returnType, types, modifiers);
280 protected override bool HasElementTypeImpl ()
282 return IsArrayImpl() || IsByRefImpl() || IsPointerImpl ();
285 protected override bool IsArrayImpl ()
287 return Type.IsArrayImpl (this);
290 [MethodImplAttribute(MethodImplOptions.InternalCall)]
291 protected extern override bool IsByRefImpl ();
293 [MethodImplAttribute (MethodImplOptions.InternalCall)]
294 protected extern override bool IsCOMObjectImpl ();
296 [MethodImplAttribute(MethodImplOptions.InternalCall)]
297 protected extern override bool IsPointerImpl ();
299 [MethodImplAttribute(MethodImplOptions.InternalCall)]
300 protected extern override bool IsPrimitiveImpl ();
302 protected override bool IsValueTypeImpl ()
304 return type_is_subtype_of (this, typeof (System.ValueType), false) &&
305 this != typeof (System.ValueType) &&
306 this != typeof (System.Enum);
309 public override object InvokeMember (string name, BindingFlags invokeAttr,
310 Binder binder, object target, object[] args,
311 ParameterModifier[] modifiers,
312 CultureInfo culture, string[] namedParameters)
315 if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
316 if ((invokeAttr & (BindingFlags.GetField |
317 BindingFlags.GetField | BindingFlags.GetProperty |
318 BindingFlags.SetProperty)) != 0)
319 throw new ArgumentException ("invokeAttr");
320 } else if (name == null)
321 throw new ArgumentNullException ("name");
322 if ((invokeAttr & BindingFlags.GetField) != 0 && (invokeAttr & BindingFlags.SetField) != 0)
323 throw new ArgumentException ("invokeAttr");
324 if ((invokeAttr & BindingFlags.GetProperty) != 0 && (invokeAttr & BindingFlags.SetProperty) != 0)
325 throw new ArgumentException ("invokeAttr");
326 if ((invokeAttr & BindingFlags.InvokeMethod) != 0 && (invokeAttr & (BindingFlags.SetProperty|BindingFlags.SetField)) != 0)
327 throw new ArgumentException ("invokeAttr");
328 if ((namedParameters != null) && ((args == null) || args.Length < namedParameters.Length))
329 throw new ArgumentException ("namedParameters cannot be more than named arguments in number");
331 /* set some defaults if none are provided :-( */
332 if ((invokeAttr & (BindingFlags.Public|BindingFlags.NonPublic)) == 0)
333 invokeAttr |= BindingFlags.Public;
334 if ((invokeAttr & (BindingFlags.Static|BindingFlags.Instance)) == 0)
335 invokeAttr |= BindingFlags.Static|BindingFlags.Instance;
338 binder = Binder.DefaultBinder;
339 if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
340 /* the name is ignored */
341 invokeAttr |= BindingFlags.DeclaredOnly;
342 ConstructorInfo[] ctors = GetConstructors (invokeAttr);
344 MethodBase ctor = binder.BindToMethod (invokeAttr, ctors, ref args, modifiers, culture, namedParameters, out state);
346 if (this.IsValueType && args == null)
347 return Activator.CreateInstanceInternal (this);
349 throw new MissingMethodException ("Constructor on type '" + FullName + "' not found.");
351 object result = ctor.Invoke (target, invokeAttr, binder, args, culture);
352 binder.ReorderArgumentArray (ref args, state);
355 if (name == String.Empty && Attribute.IsDefined (this, typeof (DefaultMemberAttribute))) {
356 DefaultMemberAttribute attr = (DefaultMemberAttribute) Attribute.GetCustomAttribute (this, typeof (DefaultMemberAttribute));
357 name = attr.MemberName;
359 bool ignoreCase = (invokeAttr & BindingFlags.IgnoreCase) != 0;
360 string throwMissingMethodDescription = null;
361 bool throwMissingFieldException = false;
363 if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
364 MethodInfo[] methods = GetMethodsByName (name, invokeAttr, ignoreCase, this);
366 MethodBase m = binder.BindToMethod (invokeAttr, methods, ref args, modifiers, culture, namedParameters, out state);
368 if (methods.Length > 0)
369 throwMissingMethodDescription = "The best match for method " + name + " has some invalid parameter.";
371 throwMissingMethodDescription = "Cannot find method " + name + ".";
373 object result = m.Invoke (target, invokeAttr, binder, args, culture);
374 binder.ReorderArgumentArray (ref args, state);
378 if ((invokeAttr & BindingFlags.GetField) != 0) {
379 FieldInfo f = GetField (name, invokeAttr);
381 return f.GetValue (target);
382 } else if ((invokeAttr & BindingFlags.GetProperty) == 0) {
383 throwMissingFieldException = true;
385 /* try GetProperty */
386 } else if ((invokeAttr & BindingFlags.SetField) != 0) {
387 if ((args == null) || args.Length != 1)
388 throw new ArgumentException ("invokeAttr");
390 FieldInfo f = GetField (name, invokeAttr);
392 f.SetValue (target, args [0]);
394 } else if ((invokeAttr & BindingFlags.SetProperty) == 0) {
395 throwMissingFieldException = true;
397 /* try SetProperty */
399 if ((invokeAttr & BindingFlags.GetProperty) != 0) {
400 PropertyInfo[] properties = GetPropertiesByName (name, invokeAttr, ignoreCase, this);
403 for (i = 0; i < properties.Length; ++i) {
404 if ((properties [i].GetGetMethod (true) != null))
407 MethodBase[] smethods = new MethodBase [count];
409 for (i = 0; i < properties.Length; ++i) {
410 MethodBase mb = properties [i].GetGetMethod (true);
412 smethods [count++] = mb;
414 MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, out state);
416 throwMissingFieldException = true;
418 object result = m.Invoke (target, invokeAttr, binder, args, culture);
419 binder.ReorderArgumentArray (ref args, state);
422 } else if ((invokeAttr & BindingFlags.SetProperty) != 0) {
423 PropertyInfo[] properties = GetPropertiesByName (name, invokeAttr, ignoreCase, this);
426 for (i = 0; i < properties.Length; ++i) {
427 if (properties [i].GetSetMethod (true) != null)
430 MethodBase[] smethods = new MethodBase [count];
432 for (i = 0; i < properties.Length; ++i) {
433 MethodBase mb = properties [i].GetSetMethod (true);
435 smethods [count++] = mb;
437 MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, out state);
439 throwMissingFieldException = true;
441 object result = m.Invoke (target, invokeAttr, binder, args, culture);
442 binder.ReorderArgumentArray (ref args, state);
446 if (throwMissingMethodDescription != null)
447 throw new MissingMethodException(throwMissingMethodDescription);
448 if (throwMissingFieldException)
449 throw new MissingFieldException("Cannot find variable " + name + ".");
454 [MethodImplAttribute(MethodImplOptions.InternalCall)]
455 public extern override Type GetElementType ();
457 public override Type UnderlyingSystemType {
459 // This has _nothing_ to do with getting the base type of an enum etc.
464 public extern override Assembly Assembly {
465 [MethodImplAttribute(MethodImplOptions.InternalCall)]
469 public override string AssemblyQualifiedName {
471 return getFullName (true, true);
475 [MethodImplAttribute(MethodImplOptions.InternalCall)]
476 private extern string getFullName(bool full_name, bool assembly_qualified);
478 public extern override Type BaseType {
479 [MethodImplAttribute(MethodImplOptions.InternalCall)]
483 public override string FullName {
485 return getFullName (true, false);
489 public override Guid GUID {
491 object[] att = GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), true);
494 return new Guid(((System.Runtime.InteropServices.GuidAttribute)att[0]).Value);
498 public override bool IsDefined (Type attributeType, bool inherit)
500 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
503 public override object[] GetCustomAttributes (bool inherit)
505 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
508 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
510 if (attributeType == null)
512 throw new ArgumentNullException("attributeType");
515 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
518 public override MemberTypes MemberType {
520 if (DeclaringType != null)
521 return MemberTypes.NestedType;
523 return MemberTypes.TypeInfo;
527 public extern override string Name {
528 [MethodImplAttribute(MethodImplOptions.InternalCall)]
532 public extern override string Namespace {
533 [MethodImplAttribute(MethodImplOptions.InternalCall)]
537 public extern override Module Module {
538 [MethodImplAttribute(MethodImplOptions.InternalCall)]
542 public extern override Type DeclaringType {
543 [MethodImplAttribute(MethodImplOptions.InternalCall)]
547 public override Type ReflectedType {
549 return DeclaringType;
553 public override RuntimeTypeHandle TypeHandle {
559 [MethodImplAttribute(MethodImplOptions.InternalCall)]
560 public extern override int GetArrayRank ();
562 public void GetObjectData(SerializationInfo info, StreamingContext context)
564 UnitySerializationHolder.GetTypeData (this, info, context);
567 public override string ToString()
569 return getFullName (false, false);
572 #if NET_2_0 || BOOTSTRAP_NET_2_0
573 [MethodImplAttribute(MethodImplOptions.InternalCall)]
574 public extern override Type [] GetGenericArguments ();
576 public override bool ContainsGenericParameters {
578 if (IsGenericParameter)
582 foreach (Type arg in GetGenericArguments ())
583 if (arg.ContainsGenericParameters)
588 return GetElementType ().ContainsGenericParameters;
594 public extern override bool IsGenericParameter {
595 [MethodImplAttribute(MethodImplOptions.InternalCall)]
599 public extern override MethodBase DeclaringMethod {
600 [MethodImplAttribute(MethodImplOptions.InternalCall)]
605 private MethodBase CheckMethodSecurity (MethodBase mb)
607 if (!SecurityManager.SecurityEnabled || (mb == null))
610 // Sadly we have no way to know which kind of security action this is
611 // so we must do it the hard way. Actually this isn't so bad
612 // because we can skip the (mb.Attributes & MethodAttributes.HasSecurity)
613 // icall required (and do it ourselves)
615 // this (unlike the Invoke step) is _and stays_ a LinkDemand (caller)
616 return SecurityManager.ReflectedLinkDemandQuery (mb) ? mb : null;