// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace System
{
+ // Contains information about the type which is expensive to compute
+ internal class MonoTypeInfo {
+ public string full_name;
+ public ConstructorInfo default_ctor;
+ }
+
[Serializable]
internal class MonoType : Type, ISerializable
{
+ [NonSerialized]
+ MonoTypeInfo type_info;
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void type_from_obj (MonoType type, Object obj);
- [MonoTODO]
internal MonoType (Object obj)
{
// this should not be used - lupus
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern TypeAttributes get_attributes (Type type);
+
+ internal ConstructorInfo GetDefaultConstructor () {
+ ConstructorInfo ctor = null;
+
+ if (type_info == null)
+ type_info = new MonoTypeInfo ();
+ if ((ctor = type_info.default_ctor) == null) {
+ const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
+ ctor = type_info.default_ctor = GetConstructor (flags, null, CallingConventions.Any, Type.EmptyTypes, null);
+ }
+
+ return ctor;
+ }
+
protected override TypeAttributes GetAttributeFlagsImpl ()
{
return get_attributes (this);
CallingConventions callConvention,
Type[] types,
ParameterModifier[] modifiers)
+ {
+ ConstructorInfo[] methods = GetConstructors (bindingAttr);
+ return GetConstructorImpl (methods, bindingAttr, binder, callConvention, types, modifiers);
+ }
+
+ internal static ConstructorInfo GetConstructorImpl (ConstructorInfo[] methods, BindingFlags bindingAttr,
+ Binder binder,
+ CallingConventions callConvention,
+ Type[] types,
+ ParameterModifier[] modifiers)
{
if (bindingAttr == BindingFlags.Default)
bindingAttr = BindingFlags.Public | BindingFlags.Instance;
- ConstructorInfo[] methods = GetConstructors (bindingAttr);
ConstructorInfo found = null;
MethodBase[] match;
int count = 0;
Type[] interfaces = GetInterfaces();
foreach (Type type in interfaces) {
- if (String.Compare (type.Name, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
+ /*We must compare against the generic type definition*/
+ Type t = type.IsGenericType ? type.GetGenericTypeDefinition () : type;
+
+ if (String.Compare (t.Name, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
return type;
- if (String.Compare (type.FullName, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
+ if (String.Compare (t.FullName, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
return type;
}
internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
{
+ if (fromNoninstanciated == null)
+ throw new ArgumentNullException ("fromNoninstanciated");
return GetCorrespondingInflatedMethod (fromNoninstanciated);
}
internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
{
+ if (fromNoninstanciated == null)
+ throw new ArgumentNullException ("fromNoninstanciated");
return GetCorrespondingInflatedConstructor (fromNoninstanciated);
}
internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
{
- return GetField (fromNoninstanciated.Name);
+ /* create sensible flags from given FieldInfo */
+ BindingFlags flags = fromNoninstanciated.IsStatic ? BindingFlags.Static : BindingFlags.Instance;
+ flags |= fromNoninstanciated.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic;
+ return GetField (fromNoninstanciated.Name, flags);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
if (count == 0)
return null;
- if (count == 1 && (types == null || types.Length == 0))
+ if (count == 1 && (types == null || types.Length == 0) &&
+ (returnType == null || returnType == props[0].PropertyType))
return props [0];
if (binder == null)
binder = Binder.DefaultBinder;
-
+
return binder.SelectProperty (bindingAttr, props, returnType, types, modifiers);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
protected extern override bool IsPrimitiveImpl ();
- protected override bool IsValueTypeImpl ()
+ public override bool IsSubclassOf (Type type)
{
- return type_is_subtype_of (this, typeof (System.ValueType), false) &&
- this != typeof (System.ValueType) &&
- this != typeof (System.Enum);
+ if (type == null)
+ throw new ArgumentNullException ("type");
+
+ return base.IsSubclassOf (type);
}
-
+
public override object InvokeMember (string name, BindingFlags invokeAttr,
Binder binder, object target, object[] args,
ParameterModifier[] modifiers,
CultureInfo culture, string[] namedParameters)
{
+ const string bindingflags_arg = "bindingFlags";
+
if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
if ((invokeAttr & (BindingFlags.GetField |
BindingFlags.GetField | BindingFlags.GetProperty |
BindingFlags.SetProperty)) != 0)
- throw new ArgumentException ("invokeAttr");
+ throw new ArgumentException (bindingflags_arg);
} else if (name == null)
throw new ArgumentNullException ("name");
if ((invokeAttr & BindingFlags.GetField) != 0 && (invokeAttr & BindingFlags.SetField) != 0)
- throw new ArgumentException ("invokeAttr");
+ throw new ArgumentException ("Cannot specify both Get and Set on a field.", bindingflags_arg);
if ((invokeAttr & BindingFlags.GetProperty) != 0 && (invokeAttr & BindingFlags.SetProperty) != 0)
- throw new ArgumentException ("invokeAttr");
- if ((invokeAttr & BindingFlags.InvokeMethod) != 0 && (invokeAttr & (BindingFlags.SetProperty|BindingFlags.SetField)) != 0)
- throw new ArgumentException ("invokeAttr");
+ throw new ArgumentException ("Cannot specify both Get and Set on a property.", bindingflags_arg);
+ if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
+ if ((invokeAttr & BindingFlags.SetField) != 0)
+ throw new ArgumentException ("Cannot specify Set on a field and Invoke on a method.", bindingflags_arg);
+ if ((invokeAttr & BindingFlags.SetProperty) != 0)
+ throw new ArgumentException ("Cannot specify Set on a property and Invoke on a method.", bindingflags_arg);
+ }
if ((namedParameters != null) && ((args == null) || args.Length < namedParameters.Length))
throw new ArgumentException ("namedParameters cannot be more than named arguments in number");
+ if ((invokeAttr & (BindingFlags.InvokeMethod|BindingFlags.CreateInstance|BindingFlags.GetField|BindingFlags.SetField|BindingFlags.GetProperty|BindingFlags.SetProperty)) == 0)
+ throw new ArgumentException ("Must specify binding flags describing the invoke operation required.", bindingflags_arg);
/* set some defaults if none are provided :-( */
if ((invokeAttr & (BindingFlags.Public|BindingFlags.NonPublic)) == 0)
if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
MethodInfo[] methods = GetMethodsByName (name, invokeAttr, ignoreCase, this);
object state = null;
+ if (args == null)
+ args = new object [0];
MethodBase m = binder.BindToMethod (invokeAttr, methods, ref args, modifiers, culture, namedParameters, out state);
if (m == null) {
if (methods.Length > 0)
else
throwMissingMethodDescription = "Cannot find method " + name + ".";
} else {
+ ParameterInfo[] parameters = m.GetParameters();
+ for (int i = 0; i < parameters.Length; ++i) {
+ if (System.Reflection.Missing.Value == args [i] && (parameters [i].Attributes & ParameterAttributes.HasDefault) != ParameterAttributes.HasDefault)
+ throw new ArgumentException ("Used Missing.Value for argument without default value", "parameters");
+ }
object result = m.Invoke (target, invokeAttr, binder, args, culture);
binder.ReorderArgumentArray (ref args, state);
return result;
}
/* try GetProperty */
} else if ((invokeAttr & BindingFlags.SetField) != 0) {
- if ((args == null) || args.Length != 1)
- throw new ArgumentException ("invokeAttr");
-
FieldInfo f = GetField (name, invokeAttr);
if (f != null) {
+ if (args == null)
+ throw new ArgumentNullException ("providedArgs");
+ if ((args == null) || args.Length != 1)
+ throw new ArgumentException ("Only the field value can be specified to set a field value.", bindingflags_arg);
f.SetValue (target, args [0]);
return null;
} else if ((invokeAttr & BindingFlags.SetProperty) == 0) {
public override string FullName {
get {
- return getFullName (true, false);
+ string fullName;
+ // This doesn't need locking
+ if (type_info == null)
+ type_info = new MonoTypeInfo ();
+ if ((fullName = type_info.full_name) == null)
+ fullName = type_info.full_name = getFullName (true, false);
+
+ return fullName;
}
}
public override MemberTypes MemberType {
get {
- if (DeclaringType != null)
+ if (DeclaringType != null && !IsGenericParameter)
return MemberTypes.NestedType;
else
return MemberTypes.TypeInfo;
return getFullName (false, false);
}
-#if NET_2_0 || BOOTSTRAP_NET_2_0
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern override Type [] GetGenericArguments ();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}
+
+ public override Type GetGenericTypeDefinition () {
+ Type res = GetGenericTypeDefinition_impl ();
+ if (res == null)
+ throw new InvalidOperationException ();
+
+ return res;
+ }
+
+#if NET_4_0
+ public override IList<CustomAttributeData> GetCustomAttributesData () {
+ return CustomAttributeData.GetCustomAttributes (this);
+ }
+
+
+ public override Array GetEnumValues () {
+ if (!IsEnum)
+ throw new ArgumentException ("Type is not an enumeration", "enumType");
+
+ return Enum.GetValues (this);
+ }
#endif
- private MethodBase CheckMethodSecurity (MethodBase mb)
+ static MethodBase CheckMethodSecurity (MethodBase mb)
{
+#if NET_2_1
+ return mb;
+#else
if (!SecurityManager.SecurityEnabled || (mb == null))
return mb;
// this (unlike the Invoke step) is _and stays_ a LinkDemand (caller)
return SecurityManager.ReflectedLinkDemandQuery (mb) ? mb : null;
+#endif
}
+
+#if NET_4_0
+ //seclevel { transparent = 0, safe-critical = 1, critical = 2}
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern int get_core_clr_security_level ();
+
+ public override bool IsSecurityTransparent
+ {
+ get { return get_core_clr_security_level () == 0; }
+ }
+
+ public override bool IsSecurityCritical
+ {
+ get { return get_core_clr_security_level () > 0; }
+ }
+
+ public override bool IsSecuritySafeCritical
+ {
+ get { return get_core_clr_security_level () == 1; }
+ }
+#endif
+
}
}