In System.Runtime.Remoting:
authorRobert Jordan <robertj@gmx.net>
Sat, 8 Sep 2007 22:28:07 +0000 (22:28 -0000)
committerRobert Jordan <robertj@gmx.net>
Sat, 8 Sep 2007 22:28:07 +0000 (22:28 -0000)
2007-08-30  Robert Jordan  <robertj@gmx.net>

* 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  <robertj@gmx.net>

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

svn path=/trunk/mcs/; revision=85525

mcs/class/corlib/System.Runtime.Remoting.Messaging/ChangeLog
mcs/class/corlib/System.Runtime.Remoting.Messaging/MethodCall.cs
mcs/class/corlib/System.Runtime.Remoting/ChangeLog
mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs

index d4989236732af7bf6ba40ba67c3dad9638763665..dc652baa22158af86c31b3077c59b1f042a7aca6 100644 (file)
@@ -1,3 +1,9 @@
+2007-09-07   Robert Jordan  <robertj@gmx.net>
+
+       * MethodCall (ResolveMethod): Handle generic methods in the
+       code that was introduced as a fix for #82240.
+       Fixes #81554.
+
 2007-09-06  Atsushi Enomoto  <atsushi@ximian.com>
 
        * LogicalCallContext.cs, MethodCall.cs, MethodCallMessageWrapper.cs,
index 7b0e2f6447161fa548840c51bc74bc1d39c990b3..452f2a35e0b285fefb9b3b4aadc61bbec7afdf60 100644 (file)
@@ -327,12 +327,23 @@ namespace System.Runtime.Remoting.Messaging {
                                        _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 + "'");
index e36082b55e00ce7261b3fecd7da167c4a194691c..67e4c4b21bbeb77ac6b13caa896644be22f43c0e 100644 (file)
@@ -1,3 +1,14 @@
+2007-08-30  Robert Jordan  <robertj@gmx.net>
+
+       * 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  <mark.probst@gmail.com>
 
        * RemotingServices.cs: Make sure InternalExecute doesn't get
index a947654ef80074f06d2ab25907c86139e4f64d0d..ddd0c8774880abf32803afd2aad4727e0769174f 100644 (file)
@@ -117,16 +117,45 @@ namespace System.Runtime.Remoting
                        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 @@ namespace System.Runtime.Remoting
                        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 @@ namespace System.Runtime.Remoting
                                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);