Пример #1
0
        internal override Expression GetExpression(List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, LabelTarget label, bool requiresReturnValue = true)
        {
            ParameterInfo[] pars = Method.GetParameters();
            Expression[]    args = new Expression[pars.Length];
            for (int i = 0; i < pars.Length; ++i)
            {
                if (i < Arguments.Arguments.Length)
                {
                    CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, pars[i].ParameterType, dynamicContext ?? typeof(object));
                    args[i] = Expression.Dynamic(binder, pars[i].ParameterType, Arguments.Arguments[i].GetExpression(parameters, locals, dataContainers, dynamicContext, label));
                }
                else
                {
                    CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, pars[i].ParameterType, dynamicContext ?? typeof(object));
                    args[i] = Expression.Dynamic(binder, pars[i].ParameterType, Expression.Constant(pars[i].DefaultValue, typeof(object)));
                }
            }
            var exp = Expression.Call(Method, args);

            if (requiresReturnValue)
            {
                return(Expression.Convert(exp, typeof(object)));
            }
            return(exp);
        }
        /// <summary>
        /// Provides implementation for binary operations. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as addition and multiplication.
        /// </summary>
        /// <returns><c>true</c> if the operation is successful; otherwise, <c>false</c>. If this method returns <c>false</c>, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.)</returns>
        /// <param name="binder">Provides information about the binary operation. The binder.Operation property returns an <see cref="T:System.Linq.Expressions.ExpressionType"/> object. For example, for the sum = first + second statement, where first and second are derived from the DynamicObject class, binder.Operation returns ExpressionType.Add.</param><param name="arg">The right operand for the binary operation. For example, for the sum = first + second statement, where first and second are derived from the DynamicObject class, <paramref name="arg"/> is equal to second.</param><param name="result">The result of the binary operation.</param>
        public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result)
        {
            object resultOfCast;

            result = null;

            if (binder.Operation != ExpressionType.Equal)
            {
                return(false);
            }

            var convert =
                Binder.Convert(CSharpBinderFlags.None, arg.GetType(), typeof(ElasticsearchDynamicValue));

            if (!TryConvert((ConvertBinder)convert, out resultOfCast))
            {
                return(false);
            }

            result = (resultOfCast == null) ?
                     Equals(arg, resultOfCast) :
                     resultOfCast.Equals(arg);

            return(true);
        }
        internal static object InvokeConvertCallSite(object target, bool explict, Type type, Type context,
                                                     ref CallSite callSite)
        {
            if (callSite == null)
            {
                LazyBinder binder = () =>
                {
                    var flags = explict
                                                            ? CSharpBinderFlags.ConvertExplicit
                                                            : CSharpBinderFlags.None;

                    return(Binder.Convert(flags, type, context));
                };
                Type binderType = typeof(ConvertBinder);

                var func = BuildProxy.GenerateCallSiteFuncType(new Type[] {}, type);

                callSite = CreateCallSite(func, binderType, binder,
                                          explict
                                              ? Invocation.ExplicitConvertBinderName
                                              : Invocation.ImplicitConvertBinderName, context);
            }
            dynamic theDynamicCallSite = callSite;

            return(theDynamicCallSite.OriginalTarget(callSite, target));
        }
            private static void AttemptExplicitCast <TFrom, TTo>()
            {
                // based on the IL generated from
                // var x = (TTo)(dynamic)default(TFrom);

                var binder   = CSharpBinder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(TTo), typeof(ConversionHelper));
                var callSite = CallSite <Func <CallSite, TFrom, TTo> > .Create(binder);

                callSite.Target(callSite, default(TFrom));
            }
Пример #5
0
        private static TTo AttemptExplicitCast <TFrom, TTo>(TFrom value)
        {
            // based on the IL generated from
            //var x = (TTo)(dynamic)value;

            var binder   = CSharpBinder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(TTo), typeof(TypeHelper));
            var callSite = CallSite <Func <CallSite, TFrom, TTo> > .Create(binder);

            //dynamic tDynCallSite = callSite;
            return(callSite.Target(callSite, value));
        }
Пример #6
0
        internal override Expression GetExpression(List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, LabelTarget label)
        {
            Expression exp;

            if (ConstructorType != null)
            {
                if (Constructor != null)
                {
                    ParameterInfo[]   info = Constructor.GetParameters();
                    List <Expression> args = new List <Expression>();
                    for (int i = 0; i < info.Length; ++i)
                    {
                        args.Add(Expression.Dynamic(Binder.Convert(CSharpBinderFlags.None, info[i].ParameterType, dynamicContext ?? typeof(object)), info[i].ParameterType, Arguments.Arguments[i].GetExpression(parameters, locals, dataContainers, dynamicContext, label)));
                    }
                    exp = Expression.New(Constructor, args);
                }
                else
                {
                    exp = Expression.New(ConstructorType);
                }
                if (Initializers != null)
                {
                    if (Initializers.Arguments.Any(token => token is AssignmentToken))
                    {
                        Func <MemberInfo, Type> getType = mem => mem is FieldInfo ? (mem as FieldInfo).FieldType : (mem as PropertyInfo).PropertyType;
                        var inits = Initializers.Arguments.Cast <AssignmentToken>().Select(token => new Tuple <MemberInfo, Expression>(token.Member, Expression.Dynamic(Binder.Convert(CSharpBinderFlags.None, getType(token.Member), dynamicContext ?? typeof(object)), getType(token.Member), token.Value.GetExpression(parameters, locals, dataContainers, dynamicContext, label))));
                        exp = Expression.MemberInit(exp as NewExpression, inits.Select(init => (MemberBinding)Expression.Bind(init.Item1, init.Item2)));
                    }
                    else
                    {
                        exp = Expression.ListInit(exp as NewExpression, ConvertInitializers(Initializers, parameters, locals, dataContainers, dynamicContext, null, label).Cast <ElementInit>());
                    }
                }
            }
            else
            {
                if (Initializers != null)
                {
                    CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, ArrayType, dynamicContext ?? typeof(object));
                    exp = Expression.NewArrayInit(ArrayType, Initializers.Arguments.Select(token => Expression.Dynamic(binder, ArrayType, token.GetExpression(parameters, locals, dataContainers, dynamicContext, label))));
                }
                else
                {
                    CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, typeof(int), dynamicContext ?? typeof(object));
                    exp = Expression.NewArrayBounds(ArrayType, Arguments.Arguments.Select(token => Expression.Dynamic(binder, typeof(int), token.GetExpression(parameters, locals, dataContainers, dynamicContext, label))));
                }
            }
            return(Expression.Convert(exp, typeof(object)));
        }
Пример #7
0
        internal override Expression GetExpression(List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, LabelTarget label, bool requiresReturnValue = true)
        {
            var value = Value.GetExpression(parameters, locals, dataContainers, dynamicContext, label);

            if (Target is InstanceMemberToken)
            {
                CallSiteBinder binder = Binder.SetMember(CSharpBinderFlags.None, (Target as InstanceMemberToken).MemberName, dynamicContext ?? typeof(object), new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
                return(Expression.Dynamic(binder, typeof(object), (Target as InstanceMemberToken).Target.GetExpression(parameters, locals, dataContainers, dynamicContext, label), value));
            }
            else
            {
                var            type   = (Target as StaticMemberToken).Member is PropertyInfo ? ((Target as StaticMemberToken).Member as PropertyInfo).PropertyType : ((Target as StaticMemberToken).Member as FieldInfo).FieldType;
                CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, type, dynamicContext ?? typeof(object));
                return(Expression.Convert(Expression.Assign(Expression.MakeMemberAccess(null, (Target as StaticMemberToken).Member), Expression.Dynamic(binder, type, value)), typeof(object)));
            }
        }
        public object AccessValueElementTest(string elementName, object value, Type type)
        {
            XElement       element        = new XElement(elementName, value);
            dynamic        dynamicElement = element.AsDynamic();
            CallSiteBinder callsiteBinder = Binder.Convert(CSharpBinderFlags.None, type,
                                                           typeof(DynamicXElementReader));

            //-----------------------------------------------------------------------------------//
            // Creating Func<CallSite, object, Type>
            //-----------------------------------------------------------------------------------//
            // For type "int" this code is equivalent to:
            // Type constructedFuncType = typeof(Func<CallSite, object, int);

            Type openFuncType        = typeof(Func <, ,>);
            Type constructedFuncType = openFuncType.MakeGenericType(
                typeof(CallSite), typeof(object), type);

            //-----------------------------------------------------------------------------------//
            // Creating CallSite<Func<CallSite, object, Type>>
            //-----------------------------------------------------------------------------------//
            // For type "int" this code is equivalent to:
            // Type constructedCallSiteType = typeof(CallSite<Func<CallSite, object, int>>);
            Type callSiteType            = typeof(CallSite <>);
            Type constructedCallSiteType = callSiteType.MakeGenericType(constructedFuncType);

            //-----------------------------------------------------------------------------------//
            // var callSite = CallSite<Func<CallSite, object, int>>.Create(callSiteBinder);
            //-----------------------------------------------------------------------------------//
            var method = constructedCallSiteType.GetMethod("Create",
                                                           BindingFlags.Static | BindingFlags.Public);
            CallSite callSite = (CallSite)method.Invoke(null, new object[] { callsiteBinder });

            //-----------------------------------------------------------------------------------//
            // int actual = callSite.Target(callSite, dynamicElement);
            //-----------------------------------------------------------------------------------//
            FieldInfo targetFieldInfo = callSite.GetType().GetField("Target");
            object    target          = targetFieldInfo.GetValue(callSite);

            // target is underlying delegate instance of type: Func<CallSite, object, int>
            var targetMethod = target.GetType().GetMethod("Invoke",
                                                          BindingFlags.Instance | BindingFlags.Public);
            object actual = targetMethod.Invoke(target, new object[] { callSite, dynamicElement });

            Console.WriteLine("Name: {0}, Value: {1}, Type: {2}", elementName, value, type);
            Console.WriteLine("Actual value: {0}", actual);
            return(actual);
        }
Пример #9
0
            private static bool AttemptExplicitCast <TFrom, TTo>()
            {
                // based on the IL generated from
                // var x = (TTo)(dynamic)default(TFrom);
                try
                {
                    var binder   = CSharpBinder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(TTo), typeof(ConversionHelper));
                    var callSite = CallSite <Func <CallSite, TFrom, TTo> > .Create(binder);

                    callSite.Target(callSite, default(TFrom));
                    return(true);
                }
                catch (RuntimeBinderException ex)
                {
                    return(!ex.Message.EndsWith(" konvertiert werden."));
                }
            }
        public void AccessValueWithBinderTest()
        {
            XElement element        = new XElement("name", 1);
            dynamic  dynamicElement = element.AsDynamic();
            // Following lines are almost equivalent (except caching)
            // to following:
            // int actual = (int)dynamicElement;

            var callsiteBinder = Binder.Convert(CSharpBinderFlags.None, typeof(int),
                                                typeof(DynamicXElementReader));

            CallSite <Func <CallSite, object, int> > callSite =
                CallSite <Func <CallSite, object, int> > .Create(callsiteBinder);

            int actual = callSite.Target(callSite, dynamicElement);

            Assert.That(actual, Is.EqualTo(1));
        }
Пример #11
0
        internal static object InvokeConvertCallSite(object target, bool explict, Type type, Type context, ref CallSite callSite)
        {
            if (callSite == null)
            {
                LazyBinder tBinder = () =>
                {
                    var tFlags = explict ? CSharpBinderFlags.ConvertExplicit : CSharpBinderFlags.None;

                    return(Binder.Convert(tFlags, type, context));
                };
                Type tBinderType = typeof(ConvertBinder);

                var tFunc = typeof(Func <, ,>).MakeGenericType(typeof(CallSite), typeof(object), type);


                callSite = CreateCallSite(tFunc, tBinderType, Unknown, tBinder,
                                          explict
                                              ? Invocation.ExplicitConvertBinderName
                                              : Invocation.ImplicitConvertBinderName, context);
            }
            dynamic tDynCallSite = callSite;

            return(tDynCallSite.Target(callSite, target));
        }
Пример #12
0
 private IEnumerable <object> ConvertInitializers(ArgumentListToken arguments, List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, Type[] expectedTypes, LabelTarget label)
 {
     foreach (TokenBase token in arguments.Arguments)
     {
         if (token is ArgumentListToken)
         {
             MethodInfo   add  = Constructor.DeclaringType.GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(m => m.Name == "Add" && m.GetParameters().Length == (token as ArgumentListToken).Arguments.Length);
             int          i    = 0;
             Expression[] exps = new Expression[add.GetParameters().Length];
             foreach (ParameterInfo info in add.GetParameters())
             {
                 CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, info.ParameterType, dynamicContext);
                 exps[i] = Expression.Dynamic(binder, info.ParameterType, (token as ArgumentListToken).Arguments[i++].GetExpression(parameters, locals, dataContainers, dynamicContext, label));
             }
             yield return(Expression.ElementInit(add, exps));
         }
         else
         {
             MethodInfo     add    = Constructor.DeclaringType.GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(m => m.Name == "Add" && m.GetParameters().Length == 1);
             CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, add.GetParameters()[0].ParameterType, dynamicContext);
             yield return(Expression.ElementInit(add, Expression.Dynamic(binder, add.GetParameters()[0].ParameterType, token.GetExpression(parameters, locals, dataContainers, dynamicContext, label))));
         }
     }
 }
Пример #13
0
        internal override Expression GetExpression(List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, LabelTarget label)
        {
            if (Lambda)
            {
                List <Tuple <string, Type> > pars = new List <Tuple <string, Type> >();
                foreach (TokenBase token in Arguments.Arguments)
                {
                    if (token is TypeCastToken)
                    {
                        pars.Add(new Tuple <string, Type>(((token as TypeCastToken).Target as ParameterToken).Name, (token as TypeCastToken).TargetType));
                    }
                    else
                    {
                        pars.Add(new Tuple <string, Type>((token as ParameterToken).Name, typeof(object)));
                    }
                }
                Dictionary <string, ConstantExpression> subLocals = new Dictionary <string, ConstantExpression>();
                foreach (var tuple in pars)
                {
                    var container = new DataContainer();
                    subLocals.Add(tuple.Item1, Expression.Constant(container));
                    dataContainers.Add(container);
                }

                List <ParameterExpression> parExps = new List <ParameterExpression>();
                Expression exp = Value.GetExpression(parExps, subLocals, dataContainers, dynamicContext, label);

                if (parExps.Count != 0)
                {
                    foreach (ParameterExpression par in parExps)
                    {
                        if (!(parameters.Any(p => p.Name == par.Name) || locals.Any(l => l.Key == par.Name)))
                        {
                            parameters.Add(par);
                        }
                        var container = new DataContainer();
                        subLocals.Add(par.Name, Expression.Constant(container));
                        dataContainers.Add(container);
                    }
                    parExps.Clear();
                    exp = Value.GetExpression(parExps, subLocals, dataContainers, dynamicContext, label);
                }

                foreach (var tuple in pars)
                {
                    parExps.Add(Expression.Parameter(tuple.Item2, tuple.Item1));
                }

                CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, Value.ReturnType, dynamicContext);

                Expression block = Expression.Block(subLocals.Zip(parExps, (l, p) => Expression.Assign(Expression.Property(l.Value, "Value"), Expression.Convert(p, typeof(object)))).Concat(new Expression[] { Expression.Dynamic(binder, Value.ReturnType, exp) }));

                Type       type   = funcTypes[pars.Count].MakeGenericType(pars.Select(t => t.Item2).Concat(new[] { Value.ReturnType }).ToArray());
                MethodInfo method = typeof(Expression).GetMethods().FirstOrDefault(m => m.Name == "Lambda" && m.IsGenericMethod && m.GetParameters().Length == 2).MakeGenericMethod(type);
                object     func   = ((dynamic)method.Invoke(null, new object[] { block, parExps.ToArray() })).Compile();

                Expression ret = Expression.Block(subLocals.Skip(parExps.Count).Select(kvp => Expression.Assign(Expression.Property(kvp.Value, "Value"), parameters.Select(p => new Tuple <string, Expression>(p.Name, p)).Concat(locals.Select(k => new Tuple <string, Expression>(k.Key, Expression.Property(k.Value, "Value")))).First(p => p.Item1 == kvp.Key).Item2)).Concat(new [] { Expression.Constant(func) as Expression }));

                return(ret);
            }
            else
            {
                List <ConstantExpression> newLocals = new List <ConstantExpression>();
                foreach (var arg in Arguments.Arguments.Cast <AssignmentToken>())
                {
                    if (locals.Any(name => name.Key == arg.Name))
                    {
                        throw new Exception("Duplicate local variable name \"" + arg.Name + "\" found.");
                    }
                    var container = new DataContainer();
                    var value     = Expression.Constant(container);
                    dataContainers.Add(container);
                    newLocals.Add(value);
                    locals.Add(arg.Name, value);
                }
                IEnumerable <BinaryExpression> assignments = Arguments.Arguments.Cast <AssignmentToken>().Zip(newLocals, (t, l) => Expression.Assign(Expression.Property(l, "Value"), t.Value.GetExpression(parameters, locals, dataContainers, dynamicContext, label)));
                Expression ret = Expression.Block(assignments.Cast <Expression>().Concat(new Expression[] { Value.GetExpression(parameters, locals, dataContainers, dynamicContext, label) }));
                foreach (var arg in Arguments.Arguments.Cast <AssignmentToken>())
                {
                    locals.Remove(arg.Name);
                }
                return(ret);
            }
        }
Пример #14
0
        public static K TryEvalCast <T, K>(T obj, Type type, CSharpBinderFlags kind, Type accessibilityContext)
        {
            var site = CallSite <Func <CallSite, T, K> > .Create(Binder.Convert(kind, type, accessibilityContext));

            return(site.Target(site, obj));
        }