* attribute.cs (GetMarshal): Work even if "DefineCustom" is
[mono.git] / mcs / class / corlib / System / MonoType.cs
index 248d756adc8ed414c1d691f25aeda11dc678140a..7c145c730d73245c98768a31966493c674c1dbc5 100644 (file)
@@ -8,13 +8,33 @@
 //     Gonzalo Paniagua (gonzalo@ximian.com)
 //
 // (c) 2001-2003 Ximian, Inc.
-// (c) 2003,2004 Novell, Inc. (http://www.novell.com)
+// Copyright (C) 2003-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.Globalization;
 using System.Reflection;
 using System.Runtime.CompilerServices;
-using System.Globalization;
 using System.Runtime.Serialization;
+using System.Security;
 
 namespace System
 {
@@ -67,7 +87,7 @@ namespace System
                        if (types == null) {
                                if (count > 1)
                                        throw new AmbiguousMatchException ();
-                               return found;
+                               return (ConstructorInfo) CheckMethodSecurity (found);
                        }
                        match = new MethodBase [count];
                        if (count == 1)
@@ -82,7 +102,7 @@ namespace System
                        }
                        if (binder == null)
                                binder = Binder.DefaultBinder;
-                       return (ConstructorInfo)binder.SelectMethod (bindingAttr, match, types, modifiers);
+                       return (ConstructorInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, match, types, modifiers));
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -180,7 +200,7 @@ namespace System
                                return null;
                        
                        if (count == 1 && typesLen == 0) 
-                               return found;
+                               return (MethodInfo) CheckMethodSecurity (found);
 
                        match = new MethodBase [count];
                        if (count == 1)
@@ -195,12 +215,33 @@ namespace System
                        }
                        
                        if (types == null) 
-                               return (MethodInfo) Binder.FindMostDerivedMatch (match);
+                               return (MethodInfo) CheckMethodSecurity (Binder.FindMostDerivedMatch (match));
 
                        if (binder == null)
                                binder = Binder.DefaultBinder;
                        
-                       return (MethodInfo)binder.SelectMethod (bindingAttr, match, types, modifiers);
+                       return (MethodInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, match, types, modifiers));
+               }
+
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               extern MethodInfo GetCorrespondingInflatedMethod (MethodInfo generic);
+
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               extern ConstructorInfo GetCorrespondingInflatedConstructor (ConstructorInfo generic);
+
+               internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
+                {
+                        return GetCorrespondingInflatedMethod (fromNoninstanciated);
+                }
+
+               internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
+               {
+                        return GetCorrespondingInflatedConstructor (fromNoninstanciated);
+               }
+
+               internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
+               {
+                       return GetField (fromNoninstanciated.Name);
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -306,8 +347,12 @@ namespace System
                                ConstructorInfo[] ctors = GetConstructors (invokeAttr);
                                object state = null;
                                MethodBase ctor = binder.BindToMethod (invokeAttr, ctors, ref args, modifiers, culture, namedParameters, out state);
-                               if (ctor == null)
-                                       throw new MissingMethodException ();
+                               if (ctor == null) {
+                                       if (this.IsValueType && args == null)
+                                               return Activator.CreateInstanceInternal (this);
+                                       
+                                       throw new MissingMethodException ("Constructor on type '" + FullName + "' not found.");
+                               }
                                object result = ctor.Invoke (target, invokeAttr, binder, args, culture);
                                binder.ReorderArgumentArray (ref args, state);
                                return result;
@@ -317,22 +362,26 @@ namespace System
                                name = attr.MemberName;
                        }
                        bool ignoreCase = (invokeAttr & BindingFlags.IgnoreCase) != 0;
+                       bool throwMissingMethodException = false;
+                       bool throwMissingFieldException = false;
                        if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
                                MethodInfo[] methods = GetMethodsByName (name, invokeAttr, ignoreCase, this);
                                object state = null;
                                MethodBase m = binder.BindToMethod (invokeAttr, methods, ref args, modifiers, culture, namedParameters, out state);
-                               if (m == null)
-                                       throw new MissingMethodException ();
-                               object result = m.Invoke (target, invokeAttr, binder, args, culture);
-                               binder.ReorderArgumentArray (ref args, state);
-                               return result;
+                               if (m == null) {
+                                       throwMissingMethodException = true;
+                               } else {
+                                       object result = m.Invoke (target, invokeAttr, binder, args, culture);
+                                       binder.ReorderArgumentArray (ref args, state);
+                                       return result;
+                               }
                        }
                        if ((invokeAttr & BindingFlags.GetField) != 0) {
                                FieldInfo f = GetField (name, invokeAttr);
                                if (f != null) {
                                        return f.GetValue (target);
                                } else if ((invokeAttr & BindingFlags.GetProperty) == 0) {
-                                       throw new MissingFieldException ();
+                                       throwMissingFieldException = true;
                                }
                                /* try GetProperty */
                        } else if ((invokeAttr & BindingFlags.SetField) != 0) {
@@ -341,7 +390,7 @@ namespace System
                                        f.SetValue (target, args [0]);
                                        return null;
                                } else if ((invokeAttr & BindingFlags.SetProperty) == 0) {
-                                       throw new MissingFieldException ();
+                                       throwMissingFieldException = true;
                                }
                                /* try SetProperty */
                        }
@@ -350,53 +399,64 @@ namespace System
                                object state = null;
                                int i, count = 0;
                                for (i = 0; i < properties.Length; ++i) {
-                                       if ((properties [i].GetGetMethod () != null))
+                                       if ((properties [i].GetGetMethod (true) != null))
                                                count++;
                                }
                                MethodBase[] smethods = new MethodBase [count];
                                count = 0;
                                for (i = 0; i < properties.Length; ++i) {
-                                       MethodBase mb = properties [i].GetGetMethod ();
+                                       MethodBase mb = properties [i].GetGetMethod (true);
                                        if (mb != null)
                                                smethods [count++] = mb;
                                }
                                MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, out state);
-                               if (m == null)
-                                       throw new MissingFieldException ();
-                               object result = m.Invoke (target, invokeAttr, binder, args, culture);
-                               binder.ReorderArgumentArray (ref args, state);
-                               return result;
+                               if (m == null) {
+                                       throwMissingFieldException = true;
+                               } else {
+                                       object result = m.Invoke (target, invokeAttr, binder, args, culture);
+                                       binder.ReorderArgumentArray (ref args, state);
+                                       return result;
+                               }
                        } else if ((invokeAttr & BindingFlags.SetProperty) != 0) {
                                PropertyInfo[] properties = GetPropertiesByName (name, invokeAttr, ignoreCase, this);
                                object state = null;
                                int i, count = 0;
                                for (i = 0; i < properties.Length; ++i) {
-                                       if (properties [i].GetSetMethod () != null)
+                                       if (properties [i].GetSetMethod (true) != null)
                                                count++;
                                }
                                MethodBase[] smethods = new MethodBase [count];
                                count = 0;
                                for (i = 0; i < properties.Length; ++i) {
-                                       MethodBase mb = properties [i].GetSetMethod ();
+                                       MethodBase mb = properties [i].GetSetMethod (true);
                                        if (mb != null)
                                                smethods [count++] = mb;
                                }
                                MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, out state);
-                               if (m == null)
-                                       throw new MissingFieldException ();
-                               object result = m.Invoke (target, invokeAttr, binder, args, culture);
-                               binder.ReorderArgumentArray (ref args, state);
-                               return result;
+                               if (m == null) {
+                                       throwMissingFieldException = true;
+                               } else {
+                                       object result = m.Invoke (target, invokeAttr, binder, args, culture);
+                                       binder.ReorderArgumentArray (ref args, state);
+                                       return result;
+                               }
                        }
+                       if (throwMissingMethodException)
+                               throw new MissingMethodException();
+                       if (throwMissingFieldException)
+                               throw new MissingFieldException();
+
                        return null;
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern override Type GetElementType ();
 
-               public extern override Type UnderlyingSystemType {
-                       [MethodImplAttribute(MethodImplOptions.InternalCall)]
-                       get;
+               public override Type UnderlyingSystemType {
+                       get {
+                               // This has _nothing_ to do with getting the base type of an enum etc.
+                               return this;
+                       }
                }
 
                public extern override Assembly Assembly {
@@ -406,12 +466,12 @@ namespace System
 
                public override string AssemblyQualifiedName {
                        get {
-                               return getFullName () + ", " + Assembly.GetName ().ToString ();
+                               return getFullName (true, true);
                        }
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern string getFullName();
+               private extern string getFullName(bool full_name, bool assembly_qualified);
 
                public extern override Type BaseType {
                        [MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -420,7 +480,7 @@ namespace System
 
                public override string FullName {
                        get {
-                               return getFullName ();
+                               return getFullName (true, false);
                        }
                }
 
@@ -442,6 +502,11 @@ namespace System
 
                public override object[] GetCustomAttributes (Type attributeType, bool inherit)
                {
+                       if (attributeType == null)
+                       {
+                               throw new ArgumentNullException("attributeType");
+                       }
+                       
                        return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
                }
 
@@ -494,7 +559,12 @@ namespace System
                        UnitySerializationHolder.GetTypeData (this, info, context);
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_1_2
+               public override string ToString()
+               {
+                       return getFullName (false, false);
+               }
+
+#if NET_2_0 || BOOTSTRAP_NET_2_0
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern override Type [] GetGenericArguments ();
 
@@ -531,5 +601,19 @@ namespace System
                        get;
                }
 #endif
+
+               private MethodBase CheckMethodSecurity (MethodBase mb)
+               {
+                       if (!SecurityManager.SecurityEnabled || (mb == null))
+                               return mb;
+
+                       // Sadly we have no way to know which kind of security action this is
+                       // so we must do it the hard way. Actually this isn't so bad 
+                       // because we can skip the (mb.Attributes & MethodAttributes.HasSecurity)
+                       // icall required (and do it ourselves)
+
+                       // this (unlike the Invoke step) is _and stays_ a LinkDemand (caller)
+                       return SecurityManager.ReflectedLinkDemandQuery (mb) ? mb : null;
+               }
        }
 }