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