瀏覽代碼

Wed Sep 11 12:49:51 CEST 2002 Paolo Molaro <[email protected]>

	* MonoType.cs, Type.cs: implemented InvokeMember.


Wed Sep 11 12:50:54 CEST 2002 Paolo Molaro <[email protected]>

	* Binder.cs: more default binder implementation.
	* FieldInfo.cs, MonoField.cs: fixed SetValue () implementation.
	* MonoMethod.cs: use the binder in the Invoke () implementation.
	Implemented custom attributes methods and ToString for constructors.

svn path=/trunk/mcs/; revision=7355
Paolo Molaro 23 年之前
父節點
當前提交
cf3b279815

+ 35 - 3
mcs/class/corlib/System.Reflection/Binder.cs

@@ -33,6 +33,20 @@ namespace System.Reflection
 			}
 		}
 		
+		internal static bool ConvertArgs (Binder binder, object[] args, ParameterInfo[] pinfo, CultureInfo culture) {
+			if (args == null && pinfo.Length == 0)
+				return true;
+			if (pinfo.Length != args.Length)
+				return false;
+			for (int i = 0; i < args.Length; ++i) {
+				object v = binder.ChangeType (args [i], pinfo[i].ParameterType, culture);
+				if ((v == null) && (args [i] != null))
+					return false;
+				args [i] = v;
+			}
+			return true;
+		}
+
 		internal sealed class Default : Binder {
 			public override FieldInfo BindToField (BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture) 
 			{
@@ -48,12 +62,29 @@ namespace System.Reflection
 			[MonoTODO]
 			public override MethodBase BindToMethod (BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state)
 			{
-				throw new NotImplementedException ();
+				Type[] types;
+				if (args == null)
+					types = Type.EmptyTypes;
+				else {
+					types = new Type [args.Length];
+					for (int i = 0; i < args.Length; ++i) {
+						if (args [i] != null)
+							types [i] = args [i].GetType ();
+					}
+				}
+				MethodBase selected = SelectMethod (bindingAttr, match, types, modifiers);
+				state = null;
+				return selected;
 			}
 
 			public override object ChangeType (object value, Type type, CultureInfo culture)
 			{
-				if (check_type (value.GetType (), type))
+				if (value == null)
+					return null;
+				Type vtype = value.GetType ();
+				if (vtype == type || type.IsAssignableFrom (vtype))
+					return value;
+				if (check_type (vtype, type))
 					return Convert.ChangeType (value, type);
 				return null;
 			}
@@ -61,7 +92,8 @@ namespace System.Reflection
 			[MonoTODO]
 			public override void ReorderArgumentArray (ref object[] args, object state)
 			{
-				throw new NotImplementedException ();
+				//do nothing until we support named arguments
+				//throw new NotImplementedException ();
 			}
 
 			private static bool check_type (Type from, Type to) {

+ 7 - 0
mcs/class/corlib/System.Reflection/ChangeLog

@@ -1,4 +1,11 @@
 
+Wed Sep 11 12:50:54 CEST 2002 Paolo Molaro <[email protected]>
+
+	* Binder.cs: more default binder implementation.
+	* FieldInfo.cs, MonoField.cs: fixed SetValue () implementation.
+	* MonoMethod.cs: use the binder in the Invoke () implementation.
+	Implemented custom attributes methods and ToString for constructors.
+
 Thu Sep 5 20:36:27 CEST 2002 Paolo Molaro <[email protected]>
 
 	* Binder.cs: finished the Binder class and implemented the default

+ 1 - 5
mcs/class/corlib/System.Reflection/FieldInfo.cs

@@ -110,13 +110,9 @@ namespace System.Reflection {
 
 		public abstract void SetValue (object obj, object val, BindingFlags invokeAttr, Binder binder, CultureInfo culture);
 
-		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private static extern void SetValueInternal (FieldInfo fi, object obj, object value);
-
 		public void SetValue (object obj, object value)
 		{
-			//FIXME: when Binder.BindToField works, use it to check conversion
-			SetValueInternal (this, obj, value);
+			SetValue (obj, value, 0, null, null);
 		}
 	}
 }

+ 9 - 1
mcs/class/corlib/System.Reflection/MonoField.cs

@@ -96,9 +96,17 @@ namespace System.Reflection {
 			return String.Format ("{0} {1}", info.type, info.name);
 		}
 
-		[MonoTODO]
+		[MethodImplAttribute(MethodImplOptions.InternalCall)]
+		private static extern void SetValueInternal (FieldInfo fi, object obj, object value);
+
 		public override void SetValue (object obj, object val, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
 		{
+			if (IsStatic && obj == null)
+				throw new ArgumentNullException ("obj");
+			if (binder == null)
+				binder = Binder.DefaultBinder;
+			object realval = binder.ChangeType (val, FieldType, culture);
+			SetValueInternal (this, obj, realval);
 		}
 	}
 }

+ 40 - 16
mcs/class/corlib/System.Reflection/MonoMethod.cs

@@ -68,10 +68,17 @@ namespace System.Reflection {
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
 		internal extern Object InternalInvoke (Object obj, Object[] parameters);
 		
-		[MonoTODO]
 		public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
-			// fixme: consider all other parameters
-			return InternalInvoke (obj, parameters);
+			if (binder == null)
+				binder = Binder.DefaultBinder;
+			ParameterInfo[] pinfo = GetParameters ();
+			if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
+				throw new ArgumentException ("parameters");
+			try {
+				return InternalInvoke (obj, parameters);
+			} catch (Exception e) {
+				throw new TargetInvocationException (e);
+			}
 		}
 
 		public override RuntimeMethodHandle MethodHandle { 
@@ -148,12 +155,21 @@ namespace System.Reflection {
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
 		internal extern Object InternalInvoke (Object obj, Object[] parameters);
 		
-		public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
-			throw new NotImplementedException ();
+		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");
+			try {
+				return InternalInvoke (obj, parameters);
+			} catch (Exception e) {
+				throw new TargetInvocationException (e);
+			}
 		}
 
-		public override Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
-			return InternalInvoke (null, parameters);
+		public override Object Invoke (BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
+			return Invoke (null, invokeAttr, binder, parameters, culture);
 		}
 
 		public override RuntimeMethodHandle MethodHandle { 
@@ -185,19 +201,27 @@ namespace System.Reflection {
 			}
 		}
 
-		[MonoTODO]
-		public override bool IsDefined (Type attribute_type, bool inherit) {
-			return false;
+		public override bool IsDefined (Type attributeType, bool inherit) {
+			return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
 		}
 
-		[MonoTODO]
-		public override object[] GetCustomAttributes (bool inherit) {
-			return null;
+		public override object[] GetCustomAttributes( bool inherit) {
+			return MonoCustomAttrs.GetCustomAttributes (this, inherit);
 		}
 
-		[MonoTODO]
-		public override object[] GetCustomAttributes (Type attributeType, bool inherit) {
-			return null;
+		public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
+			return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
+		}
+
+		public override string ToString () {
+			string parms = "";
+			ParameterInfo[] p = GetParameters ();
+			for (int i = 0; i < p.Length; ++i) {
+				if (i > 0)
+					parms = parms + ", ";
+				parms = parms + p [i].ParameterType.Name;
+			}
+			return "Void "+Name+"("+parms+")";
 		}
 	}
 }

+ 4 - 0
mcs/class/corlib/System/ChangeLog

@@ -1,4 +1,8 @@
 
+Wed Sep 11 12:49:51 CEST 2002 Paolo Molaro <[email protected]>
+
+	* MonoType.cs, Type.cs: implemented InvokeMember.
+
 Wed Sep 11 11:06:43 CEST 2002 Paolo Molaro <[email protected]>
 
 	* Delegate.cs: check the type passed to CreateDelegate is a Delegate

+ 128 - 2
mcs/class/corlib/System/MonoType.cs

@@ -280,8 +280,134 @@ namespace System
 						     ParameterModifier[] modifiers,
 						     CultureInfo culture, string[] namedParameters)
 		{
-			// FIXME
-			throw new NotImplementedException ();
+			if (name == null)
+				throw new ArgumentNullException ("name");
+
+			if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
+				if ((invokeAttr & (BindingFlags.GetField |
+						BindingFlags.GetField | BindingFlags.GetProperty |
+						BindingFlags.SetProperty)) != 0)
+					throw new ArgumentException ("invokeAttr");
+			}
+			if ((invokeAttr & BindingFlags.GetField) != 0 && (invokeAttr & BindingFlags.SetField) != 0)
+				throw new ArgumentException ("invokeAttr");
+			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");
+			if ((invokeAttr & BindingFlags.SetField) != 0 && ((args == null) || args.Length != 1))
+				throw new ArgumentException ("invokeAttr");
+			if ((namedParameters != null) && ((args == null) || args.Length < namedParameters.Length))
+				throw new ArgumentException ("namedParameters");
+
+			/* set some defaults if none are provided :-( */
+			if ((invokeAttr & (BindingFlags.Public|BindingFlags.NonPublic)) == 0)
+				invokeAttr |= BindingFlags.Public;
+			if ((invokeAttr & (BindingFlags.Static|BindingFlags.Instance)) == 0)
+				invokeAttr |= BindingFlags.Static|BindingFlags.Instance;
+
+			if (binder == null)
+				binder = Binder.DefaultBinder;
+			if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
+				/* the name is ignored */
+				invokeAttr |= BindingFlags.DeclaredOnly;
+				ConstructorInfo[] ctors = GetConstructors (invokeAttr);
+				object state = null;
+				MethodBase ctor = binder.BindToMethod (invokeAttr, ctors, ref args, modifiers, culture, namedParameters, ref state);
+				if (ctor == null)
+					throw new MissingMethodException ();
+				object result = ctor.Invoke (target, invokeAttr, binder, args, culture);
+				binder.ReorderArgumentArray (ref args, state);
+				return result;
+			}
+			if (name == String.Empty && Attribute.IsDefined (this, typeof (DefaultMemberAttribute))) {
+				DefaultMemberAttribute attr = (DefaultMemberAttribute) Attribute.GetCustomAttribute (this, typeof (DefaultMemberAttribute));
+				name = attr.MemberName;
+			}
+			bool ignoreCase = (invokeAttr & BindingFlags.IgnoreCase) != 0;
+			if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
+				MethodInfo[] methods = GetMethods (invokeAttr);
+				object state = null;
+				int i, count = 0;
+				for (i = 0; i < methods.Length; ++i) {
+					if (String.Compare (methods [i].Name, name, ignoreCase) == 0)
+						count++;
+				}
+				MethodBase[] smethods = new MethodBase [count];
+				count = 0;
+				for (i = 0; i < methods.Length; ++i) {
+					if (String.Compare (methods [i].Name, name, ignoreCase) == 0)
+						smethods [count++] = methods [i];
+				}
+				MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, ref state);
+				if (m == null)
+					throw new MissingMethodException ();
+				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 ();
+				}
+				/* try GetProperty */
+			} else if ((invokeAttr & BindingFlags.SetField) != 0) {
+				FieldInfo f = GetField (name, invokeAttr);
+				if (f != null) {
+					f.SetValue (target, args [0]);
+					return null;
+				} else if ((invokeAttr & BindingFlags.SetProperty) == 0) {
+					throw new MissingFieldException ();
+				}
+				/* try SetProperty */
+			}
+			if ((invokeAttr & BindingFlags.GetProperty) != 0) {
+				PropertyInfo[] properties = GetProperties (invokeAttr);
+				object state = null;
+				int i, count = 0;
+				for (i = 0; i < properties.Length; ++i) {
+					if (String.Compare (properties [i].Name, name, ignoreCase) == 0 && (properties [i].GetGetMethod () != null))
+						count++;
+				}
+				MethodBase[] smethods = new MethodBase [count];
+				count = 0;
+				for (i = 0; i < properties.Length; ++i) {
+					MethodBase m = properties [i].GetGetMethod ();
+					if (String.Compare (properties [i].Name, name, ignoreCase) == 0 && (m != null))
+						smethods [count++] = m;
+				}
+				MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, ref state);
+				if (m == null)
+					throw new MissingFieldException ();
+				object result = m.Invoke (target, invokeAttr, binder, args, culture);
+				binder.ReorderArgumentArray (ref args, state);
+				return result;
+			} else if ((invokeAttr & BindingFlags.SetProperty) != 0) {
+				PropertyInfo[] properties = GetProperties (invokeAttr);
+				object state = null;
+				int i, count = 0;
+				for (i = 0; i < properties.Length; ++i) {
+					if (String.Compare (properties [i].Name, name, ignoreCase) == 0 && (properties [i].GetSetMethod () != null))
+						count++;
+				}
+				MethodBase[] smethods = new MethodBase [count];
+				count = 0;
+				for (i = 0; i < properties.Length; ++i) {
+					MethodBase m = properties [i].GetSetMethod ();
+					if (String.Compare (properties [i].Name, name, ignoreCase) == 0 && (m != null))
+						smethods [count++] = m;
+				}
+				MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, ref state);
+				if (m == null)
+					throw new MissingFieldException ();
+				object result = m.Invoke (target, invokeAttr, binder, args, culture);
+				binder.ReorderArgumentArray (ref args, state);
+				return result;
+			}
+			return null;
 		}
 
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]

+ 2 - 4
mcs/class/corlib/System/Type.cs

@@ -853,18 +853,16 @@ namespace System {
 			return result;
 		}
 
-		[MonoTODO]
 		public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder,
 					    object target, object[] args)
 		{
-			throw new NotImplementedException ();
+			return InvokeMember (name, invokeAttr, binder, target, args, null, null, null);
 		}
 
-		[MonoTODO]
 		public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder,
 					    object target, object[] args, CultureInfo culture)
 		{
-			throw new NotImplementedException ();
+			return InvokeMember (name, invokeAttr, binder, target, args, null, culture, null);
 		}
 
 		public abstract object InvokeMember (string name, BindingFlags invokeAttr,