/// <summary>
 /// Helper to produce a conversion rule by calling the method to do the convert.  This version takes the parameter
 /// to be passed to the conversion function and we call it w/ our own value or w/ our Extensible.Value.
 /// </summary>
 private static DynamicMetaObject MakeConversionTargetWorker(ConversionResultKind kind, MethodTracker method, bool isImplicit, BindingRestrictions restrictions, Expression param)
 {
     return(new DynamicMetaObject(
                WrapForThrowingTry(
                    kind,
                    isImplicit,
                    AstUtils.SimpleCallHelper(
                        method.Method,
                        param
                        ),
                    method.Method.ReturnType
                    ),
                restrictions
                ));
 }
예제 #2
0
        private void MakePropertyRule(Type targetType, MemberGroup properties)
        {
            PropertyTracker info = (PropertyTracker)properties[0];

            MethodInfo setter = info.GetSetMethod(true);

            // Allow access to protected getters TODO: this should go, it supports IronPython semantics.
            if (setter != null && !setter.IsPublic && !(setter.IsFamily || setter.IsFamilyOrAssembly))
            {
                if (!PrivateBinding)
                {
                    setter = null;
                }
            }

            if (setter != null)
            {
                setter = CompilerHelpers.GetCallableMethod(setter, Binder.PrivateBinding);

                if (info.IsStatic != _isStatic)
                {
                    AddToBody(Binder.MakeStaticPropertyInstanceAccessError(info, true, Rule.Parameters).MakeErrorForRule(Rule, Binder));
                }
                else if (info.IsStatic && info.DeclaringType != targetType)
                {
                    AddToBody(Binder.MakeStaticAssignFromDerivedTypeError(targetType, info, Rule.Parameters[1], Rule.Context).MakeErrorForRule(Rule, Binder));
                }
                else if (setter.ContainsGenericParameters)
                {
                    AddToBody(Rule.MakeError(MakeGenericPropertyExpression()));
                }
                else if (setter.IsPublic && !setter.DeclaringType.IsValueType)
                {
                    if (_isStatic)
                    {
                        AddToBody(
                            Rule.MakeReturn(
                                Binder,
                                AstUtils.SimpleCallHelper(
                                    setter,
                                    Binder.ConvertExpression(
                                        Rule.Parameters[1],
                                        setter.GetParameters()[0].ParameterType,
                                        ConversionResultKind.ExplicitCast,
                                        Rule.Context
                                        )
                                    )
                                )
                            );
                    }
                    else
                    {
                        AddToBody(Rule.MakeReturn(Binder, MakeReturnValue(Binder.MakeCallExpression(Rule.Context, setter, Rule.Parameters))));
                    }
                }
                else
                {
                    // TODO: Should be able to do better w/ value types.
                    AddToBody(
                        Rule.MakeReturn(
                            Binder,
                            MakeReturnValue(
                                Ast.Call(
                                    Ast.Constant(((ReflectedPropertyTracker)info).Property), // TODO: Private binding on extension properties
                                    typeof(PropertyInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) }),
                                    AstUtils.Convert(Instance, typeof(object)),
                                    AstUtils.Convert(Rule.Parameters[1], typeof(object)),
                                    Ast.NewArrayInit(typeof(object))
                                    )
                                )
                            )
                        );
                }
            }
            else
            {
                AddToBody(Binder.MakeMissingMemberError(targetType, StringName).MakeErrorForRule(Rule, Binder));
            }
        }