using System.Runtime.Serialization;
using System.Reflection.Emit;
using System.Security;
+using System.Threading;
+using System.Text;
+
namespace System.Reflection {
[Serializable()]
internal class MonoMethod : MethodInfo, ISerializable
{
+#pragma warning disable 649
internal IntPtr mhandle;
string name;
Type reftype;
+#pragma warning restore 649
internal MonoMethod () {
}
this.mhandle = mhandle.Value;
}
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern string get_name (MethodBase method);
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern MonoMethod get_base_definition (MonoMethod method);
* binder to match the types of the method signature.
*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern Object InternalInvoke (Object obj, Object[] parameters);
-
+ internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc);
+
public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
{
if (binder == null)
binder = Binder.DefaultBinder;
ParameterInfo[] pinfo = GetParameters ();
- if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
- throw new ArgumentException ("parameters");
+ if ((parameters == null && pinfo.Length != 0) || (parameters != null && parameters.Length != pinfo.Length))
+ throw new TargetParameterCountException ("parameters do not match signature");
+
+ if ((invokeAttr & BindingFlags.ExactBinding) == 0) {
+ if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
+ throw new ArgumentException ("failed to convert parameters");
+ } else {
+ for (int i = 0; i < pinfo.Length; i++)
+ if (parameters[i].GetType() != pinfo[i].ParameterType)
+ throw new ArgumentException ("parameters do not match signature");
+ }
+
+#if !NET_2_1
if (SecurityManager.SecurityEnabled) {
// sadly Attributes doesn't tell us which kind of security action this is so
// we must do it the hard way - and it also means that we can skip calling
// Attribute (which is another an icall)
SecurityManager.ReflectedLinkDemandInvoke (this);
}
+#endif
#if NET_2_0
if (ContainsGenericParameters)
throw new InvalidOperationException ("Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.");
#endif
+ Exception exc;
+ object o = null;
+
try {
- return InternalInvoke (obj, parameters);
- } catch (InvalidOperationException) {
+ // The ex argument is used to distinguish exceptions thrown by the icall
+ // from the exceptions thrown by the called method (which need to be
+ // wrapped in TargetInvocationException).
+ o = InternalInvoke (obj, parameters, out exc);
+#if NET_2_0
+ } catch (ThreadAbortException) {
throw;
- } catch (TargetException) {
+#endif
+#if NET_2_1
+ } catch (MethodAccessException) {
throw;
+#endif
} catch (Exception e) {
throw new TargetInvocationException (e);
}
+
+ if (exc != null)
+ throw exc;
+ return o;
}
public override RuntimeMethodHandle MethodHandle {
}
public override string Name {
get {
- return name;
+ if (name != null)
+ return name;
+ return get_name (this);
}
}
return attrs;
}
+ static bool ShouldPrintFullName (Type type) {
+ return type.IsClass && (!type.IsPointer ||
+#if NET_2_0
+ (!type.GetElementType ().IsPrimitive && !type.GetElementType ().IsNested));
+#else
+ !type.GetElementType ().IsPrimitive);
+#endif
+ }
+
public override string ToString () {
- string parms = "";
+ StringBuilder sb = new StringBuilder ();
+ Type retType = ReturnType;
+ if (ShouldPrintFullName (retType))
+ sb.Append (retType.ToString ());
+ else
+ sb.Append (retType.Name);
+ sb.Append (" ");
+ sb.Append (Name);
+#if NET_2_0 || BOOTSTRAP_NET_2_0
+ if (IsGenericMethod) {
+ Type[] gen_params = GetGenericArguments ();
+ sb.Append ("[");
+ for (int j = 0; j < gen_params.Length; j++) {
+ if (j > 0)
+ sb.Append (",");
+ sb.Append (gen_params [j].Name);
+ }
+ sb.Append ("]");
+ }
+#endif
+ sb.Append ("(");
ParameterInfo[] p = GetParameters ();
for (int i = 0; i < p.Length; ++i) {
if (i > 0)
- parms = parms + ", ";
+ sb.Append (", ");
Type pt = p[i].ParameterType;
bool byref = pt.IsByRef;
if (byref)
pt = pt.GetElementType ();
- if (pt.IsClass && pt.Namespace != "")
- parms = parms + pt.Namespace + "." + pt.Name;
+ if (ShouldPrintFullName (pt))
+ sb.Append (pt.ToString ());
else
- parms = parms + pt.Name;
+ sb.Append (pt.Name);
if (byref)
- parms += " ByRef";
+ sb.Append (" ByRef");
}
- if (ReturnType.IsClass && ReturnType.Namespace != "")
- return ReturnType.Namespace + "." + ReturnType.Name + " " + Name + "(" + parms + ")";
- string generic = "";
-#if NET_2_0 || BOOTSTRAP_NET_2_0
- if (IsGenericMethod) {
- Type[] gen_params = GetGenericArguments ();
- generic = "[";
- for (int j = 0; j < gen_params.Length; j++) {
- if (j > 0)
- generic += ",";
- generic += gen_params [j].Name;
- }
- generic += "]";
+ if ((CallingConvention & CallingConventions.VarArgs) != 0) {
+ if (p.Length > 0)
+ sb.Append (", ");
+ sb.Append ("...");
}
-#endif
- return ReturnType.Name + " " + Name + generic + "(" + parms + ")";
+
+ sb.Append (")");
+ return sb.ToString ();
}
// ISerializable
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
- ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method);
+#if NET_2_0
+ Type[] genericArguments = IsGenericMethod && !IsGenericMethodDefinition
+ ? GetGenericArguments () : null;
+ MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method, genericArguments);
+#else
+ MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method);
+#endif
}
#if NET_2_0 || BOOTSTRAP_NET_2_0
- public override MethodInfo MakeGenericMethod (Type [] types)
+ public override MethodInfo MakeGenericMethod (Type [] methodInstantiation)
{
- if (types == null)
- throw new ArgumentNullException ("types");
- MethodInfo ret = MakeGenericMethod_impl (types);
+ if (methodInstantiation == null)
+ throw new ArgumentNullException ("methodInstantiation");
+ foreach (Type type in methodInstantiation)
+ if (type == null)
+ throw new ArgumentNullException ();
+
+ MethodInfo ret = MakeGenericMethod_impl (methodInstantiation);
if (ret == null)
- throw new ArgumentException (String.Format ("The method has {0} generic parameter(s) but {1} generic argument(s) were provided.", GetGenericArguments ().Length, types.Length));
+ throw new ArgumentException (String.Format ("The method has {0} generic parameter(s) but {1} generic argument(s) were provided.", GetGenericArguments ().Length, methodInstantiation.Length));
return ret;
}
internal class MonoCMethod : ConstructorInfo, ISerializable
{
+#pragma warning disable 649
internal IntPtr mhandle;
string name;
Type reftype;
+#pragma warning restore 649
public override MethodImplAttributes GetMethodImplementationFlags() {
MonoMethodInfo info;
* to match the types of the method signature.
*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern Object InternalInvoke (Object obj, Object[] parameters);
+ internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc);
public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
{
if (binder == null)
binder = Binder.DefaultBinder;
+
ParameterInfo[] pinfo = GetParameters ();
- if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
- throw new ArgumentException ("parameters");
+
+ if ((parameters == null && pinfo.Length != 0) || (parameters != null && parameters.Length != pinfo.Length))
+ throw new TargetParameterCountException ("parameters do not match signature");
+
+ if ((invokeAttr & BindingFlags.ExactBinding) == 0) {
+ if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
+ throw new ArgumentException ("failed to convert parameters");
+ } else {
+ for (int i = 0; i < pinfo.Length; i++)
+ if (parameters[i].GetType() != pinfo[i].ParameterType)
+ throw new ArgumentException ("parameters do not match signature");
+ }
if (SecurityManager.SecurityEnabled) {
// sadly Attributes doesn't tell us which kind of security action this is so
SecurityManager.ReflectedLinkDemandInvoke (this);
}
+#if NET_2_0
+ if (obj == null && DeclaringType.ContainsGenericParameters)
+ throw new MemberAccessException ("Cannot create an instance of " + DeclaringType + " because Type.ContainsGenericParameters is true.");
+#endif
+
+ if ((invokeAttr & BindingFlags.CreateInstance) != 0 && DeclaringType.IsAbstract) {
+ throw new MemberAccessException (String.Format ("Cannot create an instance of {0} because it is an abstract class", DeclaringType));
+ }
+
+ Exception exc = null;
+ object o = null;
+
try {
- return InternalInvoke (obj, parameters);
- } catch (InvalidOperationException) {
- throw;
- } catch (TargetException) {
+ o = InternalInvoke (obj, parameters, out exc);
+#if NET_2_1
+ } catch (MethodAccessException) {
throw;
+#endif
} catch (Exception e) {
throw new TargetInvocationException (e);
}
+
+ if (exc != null)
+ throw exc;
+ return (obj == null) ? o : null;
}
public override Object Invoke (BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
}
public override string Name {
get {
- return name;
+ if (name != null)
+ return name;
+ return MonoMethod.get_name (this);
}
}
return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
}
-#if NET_2_0 || BOOTSTRAP_NET_2_0
- public override bool IsGenericMethodDefinition {
- get {
- return false;
- }
- }
-
- public override bool IsGenericMethod {
- get {
- return false;
- }
- }
-#endif
-
#if NET_2_0
public override MethodBody GetMethodBody () {
return GetMethodBody (mhandle);
#endif
public override string ToString () {
- string parms = "";
+ StringBuilder sb = new StringBuilder ();
+ sb.Append ("Void ");
+ sb.Append (Name);
+ sb.Append ("(");
ParameterInfo[] p = GetParameters ();
for (int i = 0; i < p.Length; ++i) {
if (i > 0)
- parms = parms + ", ";
- parms = parms + p [i].ParameterType.Name;
+ sb.Append (", ");
+ sb.Append (p[i].ParameterType.Name);
}
- return "Void "+Name+"("+parms+")";
+ sb.Append (")");
+ return sb.ToString ();
}
// ISerializable
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
- ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor);
+ MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor);
}
}
}