Пример #1
0
        public static Action <TObject, TProperty> Set <TObject, TProperty>(string memberName, object context = null)
        {
            var callSite = CallSite <Action <CallSite, TObject, TProperty> > .Create(
                Binder.SetMember(CSharpBinderFlags.ResultDiscarded, memberName, Context(context), new[] { Arg, Arg }));

            return((obj, value) => callSite.Target(callSite, obj, value));
        }
Пример #2
0
        public TypeWrapper(Type type)
        {
            foreach (PropertyInfo p in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                string name = p.Name;
                CallSite <Action <CallSite, object, object> > set = CallSite <Action <CallSite, object, object> > .Create(
                    Binder.SetMember(
                        CSharpBinderFlags.None,
                        name,
                        type,
                        new[]
                {
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
                }));

                _setters.Add(name, set);

                CallSite <Func <CallSite, object, object> > get = CallSite <Func <CallSite, object, object> > .Create(
                    Binder.GetMember(
                        CSharpBinderFlags.None,
                        name,
                        type,
                        new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));

                _getters.Add(name, get);
            }
        }
Пример #3
0
        private static void SetObjectProperty(object target, string propertyName, object propertyValue)
        {
            var targetContext  = GetTargetContext(target);
            var callSiteBinder = Binder.SetMember(CSharpBinderFlags.None, propertyName, targetContext, SetPropertyArgumentInfo);
            var callSite       = CallSite <Func <CallSite, object, object, object> > .Create(callSiteBinder);

            callSite.Target(callSite, target, propertyValue);
        }
Пример #4
0
 private static void SetDynamically(MemberInfo member, object target, object value)
 {
     var binder = Binder.SetMember(CSharpBinderFlags.None, member.Name, member.GetMemberType(),
         new[]{
             CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
             CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
         });
     var callsite = CallSite<Func<CallSite, object, object, object>>.Create(binder);
     callsite.Target(callsite, target, value);
 }
Пример #5
0
        public static Action <TObject, TProperty> Set <TObject, TProperty>([NotNull] string memberName, [CanBeNull] object context = null)
        {
            if (memberName == null)
            {
                throw new ArgumentNullException(nameof(memberName));
            }
            var callSite = CallSite <Action <CallSite, TObject, TProperty> > .Create(
                Binder.SetMember(CSharpBinderFlags.ResultDiscarded, memberName, Context(context), new[] { Arg, Arg }));

            return((obj, value) => callSite.Target(callSite, obj, value));
        }
Пример #6
0
        public static Action <object, object> CallSiteBindSet(AccessorMember member)
        {
            var args = new List <CSharpArgumentInfo>
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            };
            var binder   = Binder.SetMember(CSharpBinderFlags.None, member.Name, member.MemberInfo.DeclaringType, args);
            var callsite = CallSite <Action <CallSite, object, object> > .Create(binder);

            return((t, v) => callsite.Target(callsite, t, v));
        }
Пример #7
0
        /// <summary>Sets a value of a given property of a dynamic <paramref name="target" /> object.</summary>
        /// <param name="target">Target object .</param>
        /// <param name="propertyName">Property name to be set.</param>
        /// <param name="value">Value to be set.</param>
        /// <returns>Value of the property.</returns>
        public static void InvokeSet(dynamic target, string propertyName, object value)
        {
            int binderHash = propertyName.GetHashCode() ^ target.GetType().GetHashCode();
            CallSite <Action <CallSite, object, object> > callSite;

            if (!SetCallSites.TryGetValue(binderHash, out callSite))
            {
                var binder = Binder.SetMember(CSharpBinderFlags.None, propertyName, target.GetType(), InvokeSetArgs);
                SetCallSites[binderHash] = callSite = CallSite <Action <CallSite, object, object> > .Create(binder);
            }

            callSite.Target(callSite, target, value);
        }
Пример #8
0
        public static void SetDynamicMember(this object obj, string name, object value)
        {
            var dynamicObject = (DynamicJsonObject)obj;

            var binder = Binder.SetMember(CSharpBinderFlags.None, name, obj.GetType(), new List <CSharpArgumentInfo>
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            });

            var callsite = CallSite <Func <CallSite, object, object, object> > .Create(binder);

            callsite.Target(callsite, obj, value);
        }
Пример #9
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)));
            }
        }
Пример #10
0
        private static Accessor GetDynamicObjectAcessor(Type type, string attributeName)
        {
            var getterBinder   = Binder.GetMember(CSharpBinderFlags.None, attributeName, type, new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
            var callsiteGetter = CallSite <Func <CallSite, object, object> > .Create(getterBinder);

            var setterBinder = Binder.SetMember(CSharpBinderFlags.None, attributeName, type, new[]
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            });
            var callsiteSetter = CallSite <Func <CallSite, object, object, object> > .Create(setterBinder);

            return(new Accessor {
                Setter = (@object, value) => callsiteSetter.Target(callsiteSetter, @object, value),
                Getter = (@object) => callsiteGetter.Target(callsiteGetter, @object)
            });
        }
Пример #11
0
        public MainWindow(DapperMediator mediator)
        {
            _mediator = mediator;
            InitializeComponent();

            dynamic myObj  = new ExpandoObject();
            var     binder = RBinder.SetMember(CSharpBinderFlags.None, "Name",
                                               typeof(object),
                                               new List <CSharpArgumentInfo>()
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            });
            var callsite = CallSite <Func <CallSite, object, object, object> > .Create(binder);

            callsite.Target(callsite, myObj, "value");
        }
Пример #12
0
        internal static object InvokeSetCallSite(object target, string name, object value, Type context, bool staticContext, ref CallSite callSite)
        {
            if (callSite == null)
            {
                LazyBinder tBinder;
                Type       tBinderType;
                if (staticContext) //CSharp Binder won't call Static properties, grrr.
                {
                    tBinder = () => {
                        var tStaticFlag = CSharpBinderFlags.ResultDiscarded;
                        if (Util.IsMono)             //Mono only works if InvokeSpecialName is set and .net only works if it isn't
                        {
                            tStaticFlag |= CSharpBinderFlags.InvokeSpecialName;
                        }

                        return(Binder.InvokeMember(tStaticFlag, "set_" + name,
                                                   null,
                                                   context,
                                                   new List <CSharpArgumentInfo>
                        {
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.IsStaticType |
                                CSharpArgumentInfoFlags.UseCompileTimeType, null),
                            CSharpArgumentInfo.Create(

                                CSharpArgumentInfoFlags.None

                                , null)
                        }));
                    };

                    tBinderType = typeof(InvokeMemberBinder);
                    callSite    = CreateCallSite <Action <CallSite, object, object> >(tBinderType, KnownMember, tBinder, name, context, staticContext: true);
                }
                else
                {
                    tBinder = () => Binder.SetMember(CSharpBinderFlags.None, name,
                                                     context,
                                                     new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            CSharpArgumentInfoFlags.None, null),
                        CSharpArgumentInfo.Create(

                            CSharpArgumentInfoFlags.None

                            , null)
                    });


                    tBinderType = typeof(SetMemberBinder);
                    callSite    = CreateCallSite <Func <CallSite, object, object, object> >(tBinderType, KnownSet, tBinder, name, context, staticContext: false);
                }
            }

            if (staticContext)
            {
                var tCallSite = (CallSite <Action <CallSite, object, object> >)callSite;
                tCallSite.Target(callSite, target, value);
                return(value);
            }
            else
            {
                var tCallSite = (CallSite <Func <CallSite, object, object, object> >)callSite;
                var tResult   = tCallSite.Target(callSite, target, value);
                return(tResult);
            }
        }
Пример #13
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());
            }
        /// <summary>
        /// Builds a <see cref="BinaryDeserializer{T}" /> for a <see cref="RecordSchema" />.
        /// </summary>
        /// <returns>
        /// A successful <see cref="BinaryDeserializerBuilderCaseResult" /> if <paramref name="type" />
        /// is not an array or primitive type and <paramref name="schema" /> is a <see cref="RecordSchema" />;
        /// an unsuccessful <see cref="BinaryDeserializerBuilderCaseResult" /> otherwise.
        /// </returns>
        /// <inheritdoc />
        public virtual BinaryDeserializerBuilderCaseResult BuildExpression(Type type, Schema schema, BinaryDeserializerBuilderContext context)
        {
            if (schema is RecordSchema recordSchema)
            {
                var underlying = Nullable.GetUnderlyingType(type) ?? type;

                if (!underlying.IsArray && !underlying.IsPrimitive)
                {
                    // since record deserialization is potentially recursive, create a top-level
                    // reference:
                    var parameter = Expression.Parameter(
                        Expression.GetDelegateType(context.Reader.Type.MakeByRefType(), underlying));

                    if (!context.References.TryGetValue((recordSchema, type), out var reference))
                    {
                        context.References.Add((recordSchema, type), reference = parameter);
                    }

                    // then build/set the delegate if it hasn’t been built yet:
                    if (parameter == reference)
                    {
                        Expression expression;

                        if (GetRecordConstructor(underlying, recordSchema) is ConstructorInfo constructor)
                        {
                            var parameters = constructor.GetParameters();

                            // map constructor parameters to fields:
                            var mapping = recordSchema.Fields
                                          .Select(field =>
                            {
                                // there will be a match or we wouldn’t have made it this far:
                                var match     = parameters.Single(parameter => IsMatch(field, parameter.Name));
                                var parameter = Expression.Parameter(match.ParameterType);

                                return(
                                    Match: match,
                                    Parameter: parameter,
                                    Assignment: (Expression)Expression.Assign(
                                        parameter,
                                        DeserializerBuilder.BuildExpression(match.ParameterType, field.Type, context)));
                            })
                                          .ToDictionary(r => r.Match, r => (r.Parameter, r.Assignment));

                            expression = Expression.Block(
                                mapping
                                .Select(d => d.Value.Parameter),
                                mapping
                                .Select(d => d.Value.Assignment)
                                .Concat(new[]
                            {
                                Expression.New(
                                    constructor,
                                    parameters
                                    .Select(parameter => mapping.ContainsKey(parameter)
                                                    ? (Expression)mapping[parameter].Parameter
                                                    : Expression.Constant(parameter.DefaultValue))),
                            }));
                        }
                        else
                        {
                            var members = underlying.GetMembers(MemberVisibility);

                            // support dynamic deserialization:
                            var value = Expression.Parameter(
                                underlying.IsAssignableFrom(typeof(ExpandoObject))
                                    ? typeof(ExpandoObject)
                                    : underlying);

                            expression = Expression.Block(
                                new[] { value },
                                new[] { (Expression)Expression.Assign(value, Expression.New(value.Type)) }
                                .Concat(recordSchema.Fields.Select(field =>
                            {
                                var match = members.SingleOrDefault(member => IsMatch(field, member));

                                Expression expression;

                                if (match == null)
                                {
                                    // always deserialize fields to advance the reader:
                                    expression = DeserializerBuilder.BuildExpression(typeof(object), field.Type, context);

                                    // fall back to a dynamic setter if the value supports it:
                                    if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(value.Type))
                                    {
                                        var flags  = CSharpBinderFlags.None;
                                        var infos  = new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) };
                                        var binder = Binder.SetMember(flags, field.Name, value.Type, infos);
                                        expression = Expression.Dynamic(binder, typeof(void), value, expression);
                                    }
                                }
                                else
                                {
                                    Expression inner;

                                    try
                                    {
                                        inner = DeserializerBuilder.BuildExpression(
                                            match switch
                                        {
                                            FieldInfo fieldMatch => fieldMatch.FieldType,
                                            PropertyInfo propertyMatch => propertyMatch.PropertyType,
                                            MemberInfo unknown => throw new InvalidOperationException($"Record fields can only be mapped to fields and properties."),
                                        },
                                            field.Type,
                                            context);
                                    }
                                    catch (Exception exception)
                                    {
                                        throw new UnsupportedTypeException(type, $"The {match.Name} member on {type} could not be mapped to the {field.Name} field on {recordSchema.FullName}.", exception);
                                    }

                                    expression = Expression.Assign(
                                        Expression.PropertyOrField(value, match.Name),
                                        inner);
                                }

                                return(expression);
                            }))
Пример #15
0
        internal static object InvokeSetCallSite(object target, string name, object value, Type context,
                                                 bool staticContext, ref CallSite callSite)
        {
            if (callSite == null)
            {
                LazyBinder binder;
                Type       binderType;
                if (staticContext)
                {
                    binder = () =>
                    {
                        var staticFlage = CSharpBinderFlags.ResultDiscarded;

                        //Mono only works if InvokeSpecialName is set and .net only works if it isn't
                        if (TypeFactorization.IsMonoRuntimeEnvironment)
                        {
                            staticFlage |= CSharpBinderFlags.InvokeSpecialName;
                        }

                        return(Binder.InvokeMember(staticFlage, "set_" + name,
                                                   null,
                                                   context,
                                                   new List <CSharpArgumentInfo>
                        {
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.IsStaticType |
                                CSharpArgumentInfoFlags.UseCompileTimeType,
                                null),
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.None,
                                null)
                        }));
                    };

                    binderType = typeof(InvokeMemberBinder);
                    callSite   = CreateCallSite <Action <CallSite, object, object> >(binderType, binder, name, context);
                }
                else
                {
                    binder = () => Binder.SetMember(CSharpBinderFlags.None, name,
                                                    context,
                                                    new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            CSharpArgumentInfoFlags.None, null),
                        CSharpArgumentInfo.Create(
                            CSharpArgumentInfoFlags.None,
                            null)
                    });

                    binderType = typeof(SetMemberBinder);
                    callSite   = CreateCallSite <Func <CallSite, object, object, object> >(binderType, binder, name, context);
                }
            }

            if (staticContext)
            {
                var staticContextheCallSite = (CallSite <Action <CallSite, object, object> >)callSite;
                staticContextheCallSite.Target(callSite, target, value);
                return(value);
            }
            else
            {
                var cs      = (CallSite <Func <CallSite, object, object, object> >)callSite;
                var tResult = cs.Target(callSite, target, value);
                return(tResult);
            }
        }
Пример #16
0
        internal static void SetValue(string name, object target, object value)
        {
            var callSite = (CallSite <Func <CallSite, object, object, object> >)Setters[name];

            if (callSite == null)
            {
                var newSite = CallSite <Func <CallSite, object, object, object> > .Create(Binder.SetMember(CSharpBinderFlags.None, name, typeof(CallSiteCache), new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null) }));

                lock (Setters)
                {
                    callSite = (CallSite <Func <CallSite, object, object, object> >)Setters[name];
                    if (callSite == null)
                    {
                        Setters[name] = callSite = newSite;
                    }
                }
            }
            callSite.Target(callSite, target, value);
        }