private static object BindMethodRaw(BindingFlags bindFlags, InvokeMemberBinder binder, HostTarget target, object[] bindArgs)
        {
            var expr = DynamicHelpers.Bind(binder, target, bindArgs).Expression;

            if (expr == null)
            {
                return(new Func <Exception>(() => new MissingMemberException(MiscHelpers.FormatInvariant("Object has no method named '{0}'", binder.Name))));
            }

            if (expr.NodeType == ExpressionType.Dynamic)
            {
                // The binding result is a dynamic call, which is indicative of COM interop. This
                // sort of binding is not very useful here; it can't be resolved to a MethodInfo
                // instance, and caching it is problematic because it includes argument bindings.
                // Falling back to reflection should work in most cases because COM interfaces
                // support neither generic nor overloaded methods.

                try
                {
                    var method = target.Type.GetMethod(binder.Name, bindFlags);
                    return((object)method ?? new Func <Exception>(() => new MissingMemberException(MiscHelpers.FormatInvariant("Object has no method named '{0}'", binder.Name))));
                }
                catch (AmbiguousMatchException exception)
                {
                    return(new Func <Exception>(() => new AmbiguousMatchException(exception.Message)));
                }
            }

            return((new MethodBindingVisitor(target.InvokeTarget, binder.Name, expr)).Result);
        }
Esempio n. 2
0
        private MethodBindResult BindMethodInternal(string name, Type[] typeArgs, object[] args, object[] bindArgs)
        {
            // create C# member invocation binder
            const CSharpBinderFlags binderFlags = CSharpBinderFlags.InvokeSimpleName | CSharpBinderFlags.ResultDiscarded;
            var binder = Binder.InvokeMember(binderFlags, name, typeArgs, accessContext ?? engine.AccessContext, CreateArgInfoEnum(bindArgs));

            // perform default binding
            var binding   = DynamicHelpers.Bind((DynamicMetaObjectBinder)binder, target, bindArgs);
            var rawResult = (new MethodBindingVisitor(target.InvokeTarget, name, binding.Expression)).Result;

            var result = MethodBindResult.Create(name, rawResult, target, args);

            if (!(result is MethodBindSuccess) && !(target is HostType) && target.Type.IsInterface)
            {
                // binding through interface failed; try base interfaces
                foreach (var interfaceType in target.Type.GetInterfaces())
                {
                    var tempTarget = HostObject.Wrap(target.InvokeTarget, interfaceType);
                    binding   = DynamicHelpers.Bind((DynamicMetaObjectBinder)binder, tempTarget, bindArgs);
                    rawResult = (new MethodBindingVisitor(target.InvokeTarget, name, binding.Expression)).Result;

                    var tempResult = MethodBindResult.Create(name, rawResult, target, args);
                    if (tempResult is MethodBindSuccess)
                    {
                        return(tempResult);
                    }
                }

                // binding through base interfaces failed; try System.Object
                var objectTarget = HostObject.Wrap(target.InvokeTarget, typeof(object));
                binding   = DynamicHelpers.Bind((DynamicMetaObjectBinder)binder, objectTarget, bindArgs);
                rawResult = (new MethodBindingVisitor(target.InvokeTarget, name, binding.Expression)).Result;

                var objectResult = MethodBindResult.Create(name, rawResult, target, args);
                if (objectResult is MethodBindSuccess)
                {
                    return(objectResult);
                }
            }

            return(result);
        }