Author: robertj
Date: 2007-09-08 18:28:07 -0400 (Sat, 08 Sep 2007)
New Revision: 85525

Modified:
   trunk/mcs/class/corlib/System.Runtime.Remoting.Messaging/ChangeLog
   trunk/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodCall.cs
   trunk/mcs/class/corlib/System.Runtime.Remoting/ChangeLog
   trunk/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs
Log:
In System.Runtime.Remoting:
2007-08-30  Robert Jordan  <[EMAIL PROTECTED]>

        * RemotingServices.cs (InternalExecuteMessage): Resolve interface
        methods correctly. Fixes #81554. Ditto for generic methods.

        * RemotingServices.cs (GetMethodBaseFromName): Reuse already computed
        FieldSetter|GetterMethods.

        * RemotingServices.cs (GetMethodBaseFromName): New overload that
        takes generic arguments into account.

In System.Runtime.Remoting.Messaging:
2007-09-07   Robert Jordan  <[EMAIL PROTECTED]>

        * MethodCall (ResolveMethod): Handle generic methods in the
        code that was introduced as a fix for #82240.
        Fixes #81554.



Modified: trunk/mcs/class/corlib/System.Runtime.Remoting/ChangeLog
===================================================================
--- trunk/mcs/class/corlib/System.Runtime.Remoting/ChangeLog    2007-09-08 
19:07:17 UTC (rev 85524)
+++ trunk/mcs/class/corlib/System.Runtime.Remoting/ChangeLog    2007-09-08 
22:28:07 UTC (rev 85525)
@@ -1,3 +1,14 @@
+2007-08-30  Robert Jordan  <[EMAIL PROTECTED]>
+
+       * RemotingServices.cs (InternalExecuteMessage): Resolve interface
+       methods correctly. Fixes #81554. Ditto for generic methods.
+
+       * RemotingServices.cs (GetMethodBaseFromName): Reuse already computed
+       FieldSetter|GetterMethods.
+
+       * RemotingServices.cs (GetMethodBaseFromName): New overload that
+       takes generic arguments into account.
+
 2007-08-15  Mark Probst  <[EMAIL PROTECTED]>
 
        * RemotingServices.cs: Make sure InternalExecute doesn't get

Modified: trunk/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs
===================================================================
--- trunk/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs  
2007-09-08 19:07:17 UTC (rev 85524)
+++ trunk/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs  
2007-09-08 22:28:07 UTC (rev 85525)
@@ -117,16 +117,45 @@
                        Type tt = target.GetType ();
                        MethodBase method;
                        if (reqMsg.MethodBase.DeclaringType == tt ||
-                               reqMsg.MethodBase == FieldSetterMethod || 
-                               reqMsg.MethodBase == FieldGetterMethod 
-                               /*|| 
reqMsg.MethodBase.DeclaringType.IsInterface*/)
+                           reqMsg.MethodBase == FieldSetterMethod || 
+                           reqMsg.MethodBase == FieldGetterMethod) {
                                method = reqMsg.MethodBase;
-                       else
-                               method = tt.GetMethod (reqMsg.MethodName, 
BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance, null, 
(Type[]) reqMsg.MethodSignature, null);
+                       } else  {
+                               method = tt.GetMethod (reqMsg.MethodName, 
methodBindings, null,
+                                       (Type[]) reqMsg.MethodSignature, null);
 
+                               // maybe an explicit interface implementation
+                               if (method == null && 
reqMsg.MethodBase.DeclaringType.IsInterface)
+                                       method = tt.GetMethod (
+                                               
reqMsg.MethodBase.DeclaringType.FullName + "." + reqMsg.MethodName,
+                                               methodBindings, null, (Type[]) 
reqMsg.MethodSignature, null);
+                       }
+
+#if NET_2_0
+                       if (reqMsg.MethodBase.IsGenericMethod) {
+                               Type[] genericArguments = 
reqMsg.MethodBase.GetGenericArguments ();
+
+                               if (method == null) {
+                                       // method is probably overloaded
+                                       method = GetGenericMethod (tt, 
reqMsg.MethodName, methodBindings,
+                                               (Type[]) 
reqMsg.MethodSignature, genericArguments);
+
+                                       // maybe an explicit interface 
implementation
+                                       if (method == null && 
reqMsg.MethodBase.DeclaringType.IsInterface)
+                                               method = GetGenericMethod (tt,
+                                                       
reqMsg.MethodBase.DeclaringType.FullName + "." + reqMsg.MethodName,
+                                                       methodBindings, 
(Type[]) reqMsg.MethodSignature, genericArguments);
+                               }
+
+                               if (method != null)
+                                       method = 
((MethodInfo)method).MakeGenericMethod (genericArguments);
+                       }
+#endif
+
                        if (method == null)
-                               throw new NullReferenceException ();
-                               
+                               throw new RemotingException (
+                                       String.Format ("Cannot resolve method 
{0}:{1}", tt, reqMsg.MethodName));
+
                        object oldContext = CallContext.SetCurrentCallContext 
(reqMsg.LogicalCallContext);
                        
                        try 
@@ -363,10 +392,135 @@
                        Type type = Type.GetType (msg.TypeName);
                        if (type == null)
                                throw new RemotingException ("Type '" + 
msg.TypeName + "' not found.");
-                               
+
                        return GetMethodBaseFromName (type, msg.MethodName, 
(Type[]) msg.MethodSignature);
                }
+
+#if NET_2_0
+
+               internal static MethodBase GetMethodBaseFromName (Type type, 
string methodName, Type[] signature, Type[] genericArguments)
+               {
+                       if (type.IsInterface) {
+                               return FindInterfaceMethod (type, methodName, 
signature, genericArguments);
+                       }
+                       else {
+                               MethodBase method = null;
+                               if (signature == null)
+                                       method = GetGenericMethod (type, 
methodName, methodBindings, genericArguments);
+                               else
+                                       method = GetGenericMethod (type, 
methodName, methodBindings, signature, genericArguments);
+                               
+                               if (method != null)
+                                       return method;
+                                       
+                               if (methodName == "FieldSetter")
+                                       return FieldSetterMethod;
+
+                               if (methodName == "FieldGetter")
+                                       return FieldGetterMethod;
+                               
+                               if (signature == null)
+                                       return type.GetConstructor 
(methodBindings, null, Type.EmptyTypes, null);
+                               else
+                                       return type.GetConstructor 
(methodBindings, null, signature, null);
+                       }
+               }
                
+               static MethodBase FindInterfaceMethod (Type type, string 
methodName, Type[] signature, Type[] genericArguments)
+               {
+                       MethodBase method = null;
+                       
+                       if (signature == null)
+                               method = GetGenericMethod (type, methodName, 
methodBindings, genericArguments);
+                       else
+                               method = GetGenericMethod (type, methodName, 
methodBindings, signature, genericArguments);
+                               
+                       if (method != null) return method;
+                       
+                       foreach (Type t in type.GetInterfaces ()) {
+                               method = FindInterfaceMethod (t, methodName, 
signature);
+                               if (method != null) return method;
+                       }
+                       
+                       return null;
+               }
+
+               // returns the generic method with the specifed generic 
arguments
+               internal static MethodInfo GetGenericMethod (Type type, string 
name, BindingFlags flags, Type[] genericArguments)
+               {
+                       if (type == null)
+                               throw new ArgumentNullException ("type");
+
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+
+                       if (genericArguments == null)
+                               throw new ArgumentNullException 
("genericArguments");
+
+                       foreach (MethodInfo mi in type.GetMethods (flags)) {
+                               if (!mi.IsGenericMethod)
+                                       continue;
+
+                               if (mi.Name != name)
+                                       continue;
+
+                               if (mi.GetGenericArguments ().Length != 
genericArguments.Length)
+                                       continue;
+
+                               return mi;
+                       }
+                       return null;
+               }
+
+               // returns the generic method with the specifed generic 
arguments
+               internal static MethodInfo GetGenericMethod (Type type, string 
name, BindingFlags flags, Type[] signature, Type[] genericArguments)
+               {
+                       if (type == null)
+                               throw new ArgumentNullException ("type");
+
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+
+                       if (signature == null)
+                               throw new ArgumentNullException ("signature");
+
+                       if (genericArguments == null)
+                               throw new ArgumentNullException 
("genericArguments");
+
+                       foreach (MethodInfo mi in type.GetMethods (flags)) {
+                               if (!mi.IsGenericMethod)
+                                       continue;
+
+                               if (mi.Name != name)
+                                       continue;
+
+                               if (mi.GetGenericArguments ().Length != 
genericArguments.Length)
+                                       continue;
+
+                               ParameterInfo[] parms = mi.GetParameters ();
+                               if (parms.Length != signature.Length)
+                                       continue;
+
+                               if (!mi.ContainsGenericParameters) {
+                                       bool mismatch = false;
+                                       for (int i = 0; i < parms.Length; i++) {
+                                               if (parms [i].ParameterType != 
signature [i]) {
+                                                       mismatch = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (mismatch)
+                                               continue;
+                               }
+
+                               return mi;
+                       }
+
+                       return null;
+               }
+
+#endif
+
                internal static MethodBase GetMethodBaseFromName (Type type, 
string methodName, Type[] signature)
                {
                        if (type.IsInterface) {
@@ -382,8 +536,11 @@
                                if (method != null)
                                        return method;
                                        
-                               if (methodName == "FieldSetter" || methodName 
== "FieldGetter")
-                                       return typeof(object).GetMethod 
(methodName, methodBindings);
+                               if (methodName == "FieldSetter")
+                                       return FieldSetterMethod;
+
+                               if (methodName == "FieldGetter")
+                                       return FieldGetterMethod;
                                
                                if (signature == null)
                                        return type.GetConstructor 
(methodBindings, null, Type.EmptyTypes, null);

Modified: trunk/mcs/class/corlib/System.Runtime.Remoting.Messaging/ChangeLog
===================================================================
--- trunk/mcs/class/corlib/System.Runtime.Remoting.Messaging/ChangeLog  
2007-09-08 19:07:17 UTC (rev 85524)
+++ trunk/mcs/class/corlib/System.Runtime.Remoting.Messaging/ChangeLog  
2007-09-08 22:28:07 UTC (rev 85525)
@@ -1,3 +1,9 @@
+2007-09-07   Robert Jordan  <[EMAIL PROTECTED]>
+
+       * MethodCall (ResolveMethod): Handle generic methods in the
+       code that was introduced as a fix for #82240.
+       Fixes #81554.
+
 2007-09-06  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
        * LogicalCallContext.cs, MethodCall.cs, MethodCallMessageWrapper.cs,

Modified: trunk/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodCall.cs
===================================================================
--- trunk/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodCall.cs      
2007-09-08 19:07:17 UTC (rev 85524)
+++ trunk/mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodCall.cs      
2007-09-08 22:28:07 UTC (rev 85525)
@@ -327,12 +327,23 @@
                                        _methodBase = 
RemotingServices.GetMethodBaseFromName (requestType, _methodName, 
_methodSignature);
                                        if (_methodBase == null)
                                                throw new RemotingException 
("Method " + _methodName + " not found in " + type);
+
                                        
                                        // If the method is implemented in an 
interface, look for the method implementation.
                                        // It can't be done in the previous 
GetMethodBaseFromName call because at that point we
                                        // may not yet have the method 
signature.
-                                       if (requestType != type && 
requestType.IsInterface)
-                                               _methodBase = 
RemotingServices.GetMethodBaseFromName (type, _methodName, (Type[]) 
MethodSignature);
+                                       if (requestType != type && 
requestType.IsInterface) {
+#if NET_2_0
+                                               if (_methodBase.IsGenericMethod)
+                                                       _methodBase = 
RemotingServices.GetMethodBaseFromName (type, _methodName, (Type[]) 
MethodSignature, _methodBase.GetGenericArguments ());
+                                               else // fall through
+#endif
+                                                       _methodBase = 
RemotingServices.GetMethodBaseFromName (type, _methodName, (Type[]) 
MethodSignature);
+                                       }
+
+                                       if (_methodBase == null)
+                                               throw new RemotingException 
("Method " + _methodName + " not found in " + type);
+
                                }
                                else
                                        throw new RemotingException ("Cannot 
cast from client type '" + _typeName + "' to server type '" + type.FullName + 
"'");

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to