[Mono-list] 100% delegates support

Ravi Pratap M ravi@ximian.com
Thu, 18 Oct 2001 22:01:55 +0530


This is a multi-part message in MIME format.

------=_NextPart_000_0007_01C15820.8060F480
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Hey guys,

    The subject says it all :-) Just committed this patch. 

    It's time to start the stress testing of my code ;-)

    Regards,

                    Ravi


------=_NextPart_000_0007_01C15820.8060F480
Content-Type: application/octet-stream;
	name="mcs-oct-18-2"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="mcs-oct-18-2"

? mcs.pdb=0A=
Index: ChangeLog=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /cvs/public/mcs/mcs/ChangeLog,v=0A=
retrieving revision 1.138=0A=
diff -u -r1.138 ChangeLog=0A=
--- ChangeLog	2001/10/18 07:01:43	1.138=0A=
+++ ChangeLog	2001/10/18 12:33:44=0A=
@@ -1,5 +1,16 @@=0A=
 2001-10-18  Ravi Pratap  <ravi@ximian.com>=0A=
 =0A=
+	* delegate.cs (Delegate::VerifyDelegate): New method to verify=0A=
+	if two delegates are compatible.=0A=
+=0A=
+	(NewDelegate::DoResolve): Update to take care of the case when=0A=
+	we instantiate a delegate from another delegate.=0A=
+=0A=
+	* typemanager.cs (FindMembers): Don't even try to look up members=0A=
+	of Delegate types for now.=0A=
+=0A=
+2001-10-18  Ravi Pratap  <ravi@ximian.com>=0A=
+=0A=
 	* delegate.cs (NewDelegate): New class to take care of delegate=0A=
 	instantiation.=0A=
 =0A=
Index: delegate.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /cvs/public/mcs/mcs/delegate.cs,v=0A=
retrieving revision 1.9=0A=
diff -u -r1.9 delegate.cs=0A=
--- delegate.cs	2001/10/18 07:01:43	1.9=0A=
+++ delegate.cs	2001/10/18 12:33:44=0A=
@@ -151,6 +151,10 @@=0A=
 		=09
 		}
=20
+		// <summary>
+		//  Verifies whether the method in question is compatible with the =
delegate
+		//  Returns the method itself if okay and null if not.
+		// </summary>
 		public MethodBase VerifyMethod (MethodBase mb, Location loc)
 		{
 			ParameterData pd =3D Invocation.GetParameterData (mb);
@@ -187,6 +191,10 @@=0A=
 			return null;
 		}
=20
+		// <summary>
+		//  Verifies whether the invocation arguments are compatible with the
+		//  delegate's target method
+		// </summary>
 		public bool VerifyApplicability (EmitContext ec, ArrayList args, =
Location loc)
 		{
 			int arg_count;
@@ -231,7 +239,34 @@=0A=
=20
 			return true;
 		}
-  	=09
+
+		// <summary>
+		//  Verifies whether the delegate in question is compatible with this =
one in
+		//  order to determine if instantiation from the same is possible.
+		// </summary>
+		public bool VerifyDelegate (Delegate del)
+		{
+			if (ret_type !=3D del.TargetReturnType)
+				return false;
+
+			Type [] other_param_types =3D del.ParameterTypes;
+		=09
+			if (param_types.Length !=3D other_param_types.Length)
+				return false;
+
+			for (int i =3D param_types.Length; i > 0; ) {
+				i--;
+
+				if (param_types [i] !=3D other_param_types [i])
+					return false;
+			}
+
+			// FIXME : Hey, what about parameter modifiers ?
+
+			return true;
+
+		}
+	=09
 		public string FullDelegateDesc ()
 		{
 			StringBuilder sb =3D new StringBuilder (TypeManager.CSharpName =
(System.Type.GetType (ReturnType)));
@@ -282,6 +317,19 @@=0A=
 				delegate_method =3D value;
 			}
 		}
+
+		public Type TargetReturnType {
+			get {
+				return ret_type;
+			}
+		}
+
+		public Type [] ParameterTypes {
+			get {
+				return param_types;
+			}
+		}
+	=09
 	}
=20
 	public class NewDelegate : Expression {
@@ -348,10 +396,35 @@=0A=
 			=09
 				eclass =3D ExprClass.Value;
 				return this;
-			} else {
-				Report.Error (-200, Location, "Cannot handle delegate instantiation =
from other delegates");
+			}
+
+			Type e_type =3D e.Type;
+
+			Delegate d =3D TypeManager.LookupDelegate (e_type);
+
+			if (d =3D=3D null) {
+				Report.Error (-12, Location, "Cannot create a delegate from =
something " +
+					      "not a delegate or a method.");
 				return null;
 			}
+
+			// This is what MS's compiler reports. We could always choose
+			// to be more verbose and actually give delegate-level specifics
+		=09
+			if (!d.VerifyDelegate (del)) {
+				Report.Error (29, Location, "Cannot implicitly convert type '" + =
d.Name + "' " +
+					      "to type '" + del.Name + "'");
+				return null;
+			}
+
+			delegate_instance_expr =3D d.InstanceExpression;
+			delegate_method        =3D d.TargetMethod;
+		=09
+			del.InstanceExpression =3D d.InstanceExpression;
+			del.TargetMethod       =3D d.TargetMethod;
+		=09
+			eclass =3D ExprClass.Value;
+			return this;
 		}
 	=09
 		public override void Emit (EmitContext ec)
Index: typemanager.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /cvs/public/mcs/mcs/typemanager.cs,v=0A=
retrieving revision 1.31=0A=
diff -u -r1.31 typemanager.cs=0A=
--- typemanager.cs	2001/10/17 09:25:26	1.31=0A=
+++ typemanager.cs	2001/10/18 12:34:03=0A=
@@ -318,6 +318,9 @@=0A=
 	public MemberInfo [] FindMembers (Type t, MemberTypes mt, BindingFlags =
bf, MemberFilter filter, object criteria)=0A=
 	{=0A=
 		TypeContainer tc;=0A=
+=0A=
+		if (IsDelegateType (t))=0A=
+		        return null;=0A=
 		=0A=
 		tc =3D (TypeContainer) builder_to_container [t];=0A=
 		=0A=

------=_NextPart_000_0007_01C15820.8060F480--