Пример #1
0
        internal static object InvokeGetIndexCallSite(object target, object[] indexes, string[] argNames, Type context, bool tStaticContext, ref CallSite callSite)
        {
            LazyBinder tBinder     = null;
            Type       tBinderType = null;

            if (callSite == null)
            {
                tBinder = () => {
                    var tList = GetBindingArgumentList(indexes, argNames,
                                                       tStaticContext);
                    return(Binder.GetIndex(CSharpBinderFlags.None, context, tList));
                };
                tBinderType = typeof(GetIndexBinder);
            }

            return(InvokeMember <object>(ref callSite, tBinderType, tBinder, Invocation.IndexBinderName, tStaticContext, context, argNames, target, indexes));
        }
 internal static CallSiteBinder GetIndexBinder()
 {
     return(Binder.GetIndex(CSharpBinderFlags.None, null, GetArgInfo(2)));
 }
Пример #3
0
            private static Action <IInvocation> CompileInvoker(MethodInfo method)
            {
                var methodParameters    = method.GetParameters();
                var invocationParameter = Expression.Parameter(typeof(IInvocation), "invocation");

                var targetAndArgumentInfos = Pack(
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                    methodParameters.Select(
                        mp => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.NamedArgument, mp.Name))).ToArray();

                var targetAndArguments = Pack <Expression>(
                    Expression.Property(invocationParameter, invocationParameter.Type, "InvocationTarget"),
                    methodParameters.Select(
                        (mp, index) =>
                        Expression.Convert(
                            Expression.ArrayIndex(
                                Expression.Property(invocationParameter, invocationParameter.Type,
                                                    "Arguments"),
                                Expression.Constant(index)), mp.ParameterType))).ToArray();

                Expression body = null;

                if (method.IsSpecialName)
                {
                    if (method.Name.Equals("get_Item"))
                    {
                        body = Expression.Dynamic(
                            Binder.GetIndex(
                                CSharpBinderFlags.InvokeSpecialName,
                                typeof(object),
                                targetAndArgumentInfos),
                            typeof(object),
                            targetAndArguments);
                    }

                    if (body == null && method.Name.Equals("set_Item"))
                    {
                        var targetAndArgumentInfosWithoutTheNameValue = Pack(
                            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                            methodParameters.Select(
                                mp => mp.Name == "value" ? CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) : CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.NamedArgument, mp.Name)));

                        body = Expression.Dynamic(
                            Binder.SetIndex(
                                CSharpBinderFlags.InvokeSpecialName,
                                typeof(object),
                                targetAndArgumentInfosWithoutTheNameValue),
                            typeof(object),
                            targetAndArguments);
                    }

                    if (body == null && method.Name.StartsWith("get_"))
                    {
                        //  Build lambda containing the following call site:
                        //  (IInvocation invocation) => {
                        //      invocation.ReturnValue = (object) ((dynamic)invocation.InvocationTarget).{method.Name};
                        //  }
                        body = Expression.Dynamic(
                            Binder.GetMember(
                                CSharpBinderFlags.InvokeSpecialName,
                                method.Name.Substring("get_".Length),
                                typeof(object),
                                targetAndArgumentInfos),
                            typeof(object),
                            targetAndArguments);
                    }

                    if (body == null && method.Name.StartsWith("set_"))
                    {
                        body = Expression.Dynamic(
                            Binder.SetMember(
                                CSharpBinderFlags.InvokeSpecialName,
                                method.Name.Substring("set_".Length),
                                typeof(object),
                                targetAndArgumentInfos),
                            typeof(object),
                            targetAndArguments);
                    }
                }
                if (body == null)
                {
                    //  Build lambda containing the following call site:
                    //  (IInvocation invocation) => {
                    //      invocation.ReturnValue = (object) ((dynamic)invocation.InvocationTarget).{method.Name}(
                    //          {methodParameters[*].Name}: ({methodParameters[*].Type})invocation.Arguments[*],
                    //          ...);
                    //  }


                    body = Expression.Dynamic(
                        Binder.InvokeMember(
                            CSharpBinderFlags.None,
                            method.Name,
                            null,
                            typeof(object),
                            targetAndArgumentInfos),
                        typeof(object),
                        targetAndArguments);
                }

                if (method.ReturnType != typeof(void))
                {
                    body = Expression.Assign(
                        Expression.Property(invocationParameter, invocationParameter.Type, "ReturnValue"),
                        Expression.Convert(body, typeof(object)));
                }

                var lambda = Expression.Lambda <Action <IInvocation> >(body, invocationParameter);

                return(lambda.Compile());
            }
Пример #4
0
        /// <summary>
        /// Returns an Expression that accesses a member on an Expression
        /// </summary>
        /// <param name="isFunction">Determines whether the member being accessed is a function or a property</param>
        /// <param name="isCall">Determines whether the member returns void</param>
        /// <param name="le">The expression that contains the member to be accessed</param>
        /// <param name="membername">The name of the member to access</param>
        /// <param name="args">Optional list of arguments to be passed if the member is a method</param>
        /// <returns></returns>
        public static Expression MemberAccess(bool isFunction, bool isCall, Expression le, string membername, List <Expression> args)
        {
            var argTypes = args.Select(x => x.Type);

            Expression instance = null;
            Type       type     = null;

            var isDynamic     = false;
            var isRuntimeType = false;

            if (le.Type.Name == "RuntimeType")
            {
                isRuntimeType = true;
                type          = ((Type)((ConstantExpression)le).Value);
            }
            else
            {
                type      = le.Type;
                instance  = le;
                isDynamic = type.IsDynamic();
            }

            if (isFunction)
            {
                if (isDynamic)
                {
                    var expArgs = new List <Expression> {
                        instance
                    };

                    expArgs.AddRange(args);

                    if (isCall)
                    {
                        var binderMC = Binder.InvokeMember(
                            CSharpBinderFlags.ResultDiscarded,
                            membername,
                            null,
                            type,
                            expArgs.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null))
                            );

                        return(Expression.Dynamic(binderMC, typeof(void), expArgs));
                    }

                    var binderM = Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        membername,
                        null,
                        type,
                        expArgs.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null))
                        );

                    return(Expression.Dynamic(binderM, typeof(object), expArgs));
                }
                else
                {
                    var mis        = MethodResolution.GetApplicableMembers(type, membername, args);
                    var methodInfo = (MethodInfo)mis[0];

                    if (methodInfo != null)
                    {
                        var parameterInfos = methodInfo.GetParameters();

                        foreach (var parameterInfo in parameterInfos)
                        {
                            var index = parameterInfo.Position;

                            args[index] = TypeConversion.Convert(args[index], parameterInfo.ParameterType);
                        }

                        return(Expression.Call(instance, methodInfo, args.ToArray()));
                    }

                    var match = MethodResolution.GetExactMatch(type, instance, membername, args) ??
                                MethodResolution.GetParamsMatch(type, instance, membername, args);

                    if (match != null)
                    {
                        return(match);
                    }
                }
            }
            else
            {
                if (isDynamic)
                {
                    var binder = Binder.GetMember(
                        CSharpBinderFlags.None,
                        membername,
                        type,
                        new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }
                        );

                    var result = Expression.Dynamic(binder, typeof(object), instance);


                    if (args.Count > 0)
                    {
                        var expArgs = new List <Expression>()
                        {
                            result
                        };

                        expArgs.AddRange(args);

                        var indexedBinder = Binder.GetIndex(
                            CSharpBinderFlags.None,
                            type,
                            expArgs.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null))
                            );

                        result =
                            Expression.Dynamic(indexedBinder, typeof(object), expArgs);
                    }

                    return(result);
                }
                else
                {
                    Expression exp = null;

                    var propertyInfo = type.GetProperty(membername);
                    if (propertyInfo != null)
                    {
                        exp = Expression.Property(instance, propertyInfo);
                    }
                    else
                    {
                        var fieldInfo = type.GetField(membername);
                        if (fieldInfo != null)
                        {
                            exp = Expression.Field(instance, fieldInfo);
                        }
                    }

                    if (exp != null)
                    {
                        if (args.Count > 0)
                        {
                            return(Expression.ArrayAccess(exp, args));
                        }
                        else
                        {
                            return(exp);
                        }
                    }
                }
            }

            throw new Exception(string.Format("Member not found: {0}.{1}", le.Type.Name, membername));
        }