private static MethodInfo[] GetCallableMethods(MemberGroup members)
        {
            MethodInfo[] methods = new MethodInfo[members.Count];

            for (int i = 0; i < members.Count; i++)
            {
                methods[i] = CompilerHelpers.GetCallableMethod(((MethodTracker)members[i]).Method);
            }
            return(methods);
        }
Beispiel #2
0
        private void MakeMethodBaseRule(MethodBase[] targets)
        {
            Type[]     argTypes; // will not include implicit instance argument (if any)
            SymbolId[] argNames; // will include ArgumentKind.Dictionary keyword names


            GetArgumentNamesAndTypes(out argNames, out argTypes);

            Type[]    bindingArgs = argTypes; // will include instance argument (if any)
            CallTypes callType    = CallTypes.None;

            if (_instance != null)
            {
                bindingArgs = ArrayUtils.Insert(InstanceType, argTypes);
                callType    = CallTypes.ImplicitInstance;
            }

            if (_reversedOperator && bindingArgs.Length >= 2)
            {
                // we swap the arguments before binding, and swap back before calling.
                ArrayUtils.SwapLastTwo(bindingArgs);
                if (argNames.Length >= 2)
                {
                    ArrayUtils.SwapLastTwo(argNames);
                }
            }

            // attempt to bind to an individual method
            MethodBinder  binder = MethodBinder.MakeBinder(Binder, GetTargetName(targets), targets, argNames, NarrowingLevel.None, _maxLevel);
            BindingTarget bt     = binder.MakeBindingTarget(callType, bindingArgs);

            if (bt.Success)
            {
                // if we succeed make the target for the rule
                MethodBase target       = bt.Method;
                MethodInfo targetMethod = target as MethodInfo;

                if (targetMethod != null)
                {
                    target = CompilerHelpers.GetCallableMethod(targetMethod, Binder.PrivateBinding);
                }

                Expression[] exprargs = FinishTestForCandidate(bt.ArgumentTests, argTypes);

                _rule.Target = _rule.MakeReturn(
                    Binder,
                    bt.MakeExpression(_rule, exprargs));
            }
            else
            {
                // make an error rule
                MakeInvalidParametersRule(bt);
            }
        }
        private MethodInfo ResolveGetter()
        {
            MethodInfo getter = GetGetMethod(true);

            if (getter == null)
            {
                return(null);
            }

            // Allow access to protected getters TODO: this should go, it supports IronPython semantics.
            if (!getter.IsPublic && !(getter.IsFamily || getter.IsFamilyOrAssembly))
            {
                if (!ScriptDomainManager.Options.PrivateBinding)
                {
                    getter = null;
                }
            }
            return(CompilerHelpers.GetCallableMethod(getter));
        }
Beispiel #4
0
        private void MakePropertyRule(SetOrDeleteMemberInfo memInfo, DynamicMetaObject instance, DynamicMetaObject target, Type targetType, MemberGroup properties, DynamicMetaObject errorSuggestion)
        {
            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.IsProtected())
            {
                if (!PrivateBinding)
                {
                    setter = null;
                }
            }

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

                if (info.IsStatic != (instance == null))
                {
                    memInfo.Body.FinishCondition(
                        errorSuggestion ?? MakeError(
                            MakeStaticPropertyInstanceAccessError(
                                info,
                                true,
                                instance,
                                target
                                ),
                            typeof(object)
                            )
                        );
                }
                else if (info.IsStatic && info.DeclaringType != targetType)
                {
                    memInfo.Body.FinishCondition(
                        errorSuggestion ?? MakeError(
                            MakeStaticAssignFromDerivedTypeError(targetType, instance, info, target, memInfo.ResolutionFactory),
                            typeof(object)
                            )
                        );
                }
                else if (setter.ContainsGenericParameters)
                {
                    memInfo.Body.FinishCondition(
                        MakeGenericPropertyExpression(memInfo)
                        );
                }
                else if (setter.IsPublic && !setter.DeclaringType.IsValueType)
                {
                    if (instance == null)
                    {
                        memInfo.Body.FinishCondition(
                            Ast.Block(
                                AstUtils.SimpleCallHelper(
                                    setter,
                                    ConvertExpression(
                                        target.Expression,
                                        setter.GetParameters()[0].ParameterType,
                                        ConversionResultKind.ExplicitCast,
                                        memInfo.ResolutionFactory
                                        )
                                    ),
                                Ast.Constant(null)
                                )
                            );
                    }
                    else
                    {
                        memInfo.Body.FinishCondition(
                            MakeReturnValue(
                                MakeCallExpression(memInfo.ResolutionFactory, setter, instance, target),
                                target
                                )
                            );
                    }
                }
                else
                {
                    // TODO: Should be able to do better w/ value types.
                    memInfo.Body.FinishCondition(
                        MakeReturnValue(
                            Ast.Call(
                                AstUtils.Constant(((ReflectedPropertyTracker)info).Property), // TODO: Private binding on extension properties
                                typeof(PropertyInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) }),
                                instance == null ? AstUtils.Constant(null) : AstUtils.Convert(instance.Expression, typeof(object)),
                                AstUtils.Convert(
                                    ConvertExpression(
                                        target.Expression,
                                        setter.GetParameters()[0].ParameterType,
                                        ConversionResultKind.ExplicitCast,
                                        memInfo.ResolutionFactory
                                        ),
                                    typeof(object)
                                    ),
                                Ast.NewArrayInit(typeof(object))
                                ),
                            target
                            )
                        );
                }
            }
            else
            {
                memInfo.Body.FinishCondition(
                    errorSuggestion ?? MakeError(
                        MakeMissingMemberErrorForAssignReadOnlyProperty(targetType, instance, memInfo.Name), typeof(object)
                        )
                    );
            }
        }
        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 (!ScriptDomainManager.Options.PrivateBinding)
                {
                    setter = null;
                }
            }

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

                if (info.IsStatic != _isStatic)
                {
                    // TODO: Too python specific
                    AddToBody(Binder.MakeReadOnlyMemberError(Rule, targetType, StringName));
                }
                else if (setter.ContainsGenericParameters)
                {
                    AddToBody(Rule.MakeError(MakeGenericPropertyExpression()));
                }
                else if (setter.IsPublic && !setter.DeclaringType.IsValueType)
                {
                    if (_isStatic)
                    {
                        AddToBody(
                            Rule.MakeReturn(
                                Binder,
                                Ast.SimpleCallHelper(
                                    setter,
                                    Binder.ConvertExpression(
                                        Rule.Parameters[1],
                                        setter.GetParameters()[0].ParameterType
                                        )
                                    )
                                )
                            );
                    }
                    else
                    {
                        AddToBody(Rule.MakeReturn(Binder, MakeReturnValue(Binder.MakeCallExpression(setter, Rule.Parameters))));
                    }
                }
                else
                {
                    // TODO: Should be able to do better w/ value types.
                    AddToBody(
                        Rule.MakeReturn(
                            Binder,
                            MakeReturnValue(
                                Ast.Call(
                                    Ast.RuntimeConstant(((ReflectedPropertyTracker)info).Property), // TODO: Private binding on extension properties
                                    typeof(PropertyInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) }),
                                    Ast.ConvertHelper(Instance, typeof(object)),
                                    Ast.ConvertHelper(Rule.Parameters[1], typeof(object)),
                                    Ast.NewArray(typeof(object[]))
                                    )
                                )
                            )
                        );
                }
            }
            else
            {
                AddToBody(Binder.MakeMissingMemberError(Rule, targetType, StringName));
            }
        }
        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));
            }
        }
Beispiel #7
0
        private void MakeMethodBaseRule(MethodBase[] targets)
        {
            Type[]     testTypes, argTypes;
            SymbolId[] argNames;

            //If an instance is explicitly passed in as an argument, ignore it.
            //Calls that need an instance will pick it up from the bound objects
            //passed in or the rule. CallType can differentiate between the type
            //of call during method binding.
            int instanceIndex = Action.Signature.IndexOf(ArgumentKind.Instance);

            if (instanceIndex > -1)
            {
                _args = ArrayUtils.RemoveAt(_args, instanceIndex + 1);
            }

            GetArgumentNamesAndTypes(out argNames, out argTypes);

            Type[]   bindingArgs = argTypes;
            CallType callType    = CallType.None;

            if (_instance != null)
            {
                bindingArgs = ArrayUtils.Insert(_instance.Type, argTypes);
                callType    = CallType.ImplicitInstance;
            }

            if (_reversedOperator && bindingArgs.Length >= 2)
            {
                // we swap the arguments before binding, and swap back before calling.
                ArrayUtils.SwapLastTwo(bindingArgs);
                if (argNames.Length >= 2)
                {
                    ArrayUtils.SwapLastTwo(argNames);
                }
            }

            // attempt to bind to an individual method
            MethodBinder    binder = MethodBinder.MakeBinder(Binder, GetTargetName(targets), targets, GetBinderType(targets), argNames);
            MethodCandidate cand   = binder.MakeBindingTarget(callType, bindingArgs, out testTypes);

            if (cand != null)
            {
                // if we succeed make the target for the rule
                MethodBase target       = cand.Target.Method;
                MethodInfo targetMethod = target as MethodInfo;

                if (targetMethod != null)
                {
                    target = CompilerHelpers.GetCallableMethod(targetMethod);
                }

                if (!MakeActionOnCallRule(target))
                {
                    Expression[] exprargs = FinishTestForCandidate(testTypes, argTypes);

                    _rule.SetTarget(_rule.MakeReturn(
                                        Binder,
                                        cand.Target.MakeExpression(Binder, _rule, exprargs, testTypes)));
                }
            }
            else
            {
                // make an error rule
                MakeInvalidParametersRule(binder, callType, targets);
            }
        }
Beispiel #8
0
        internal Expression MakeExpression(ParameterBinder parameterBinder, IList <Expression> parameters)
        {
            bool[]       usageMarkers;
            Expression[] spilledArgs;
            Expression[] args = GetArgumentExpressions(parameterBinder, parameters, out usageMarkers, out spilledArgs);

            MethodBase mb = Method;
            MethodInfo mi = mb as MethodInfo;
            Expression ret, call;

            if (!mb.IsPublic || (mb.DeclaringType != null && !mb.DeclaringType.IsVisible))
            {
                if (mi != null)
                {
                    mi = CompilerHelpers.GetCallableMethod(mi, _binder._binder.PrivateBinding);
                    if (mi != null)
                    {
                        mb = mi;
                    }
                }
            }

            ConstructorInfo ci = mb as ConstructorInfo;

            Debug.Assert(mi != null || ci != null);
            if (mb.IsPublic && (mb.DeclaringType == null || mb.DeclaringType.IsVisible))
            {
                // public method
                if (mi != null)
                {
                    Expression instance = mi.IsStatic ? null : _instanceBuilder.ToExpression(parameterBinder, parameters, usageMarkers);
                    call = AstUtils.SimpleCallHelper(instance, mi, args);
                }
                else
                {
                    call = AstUtils.SimpleNewHelper(ci, args);
                }
            }
            else
            {
                // Private binding, invoke via reflection
                if (mi != null)
                {
                    Expression instance = mi.IsStatic ? Ast.Constant(null) : _instanceBuilder.ToExpression(parameterBinder, parameters, usageMarkers);
                    Debug.Assert(instance != null, "Can't skip instance expression");

                    call = Ast.Call(
                        typeof(BinderOps).GetMethod("InvokeMethod"),
                        Ast.Constant(mi),
                        AstUtils.Convert(instance, typeof(object)),
                        AstUtils.NewArrayHelper(typeof(object), args)
                        );
                }
                else
                {
                    call = Ast.Call(
                        typeof(BinderOps).GetMethod("InvokeConstructor"),
                        Ast.Constant(ci),
                        AstUtils.NewArrayHelper(typeof(object), args)
                        );
                }
            }

            if (spilledArgs != null)
            {
                call = Expression.Block(spilledArgs.AddLast(call));
            }

            ret = _returnBuilder.ToExpression(parameterBinder, _argBuilders, parameters, call);

            List <Expression> updates = null;

            for (int i = 0; i < _argBuilders.Count; i++)
            {
                Expression next = _argBuilders[i].UpdateFromReturn(parameterBinder, parameters);
                if (next != null)
                {
                    if (updates == null)
                    {
                        updates = new List <Expression>();
                    }
                    updates.Add(next);
                }
            }

            if (updates != null)
            {
                if (ret.Type != typeof(void))
                {
                    ParameterExpression temp = Ast.Variable(ret.Type, "$ret");
                    updates.Insert(0, Ast.Assign(temp, ret));
                    updates.Add(temp);
                    ret = Ast.Block(new [] { temp }, updates.ToArray());
                }
                else
                {
                    updates.Insert(0, ret);
                    ret = Ast.Convert(
                        Ast.Block(updates.ToArray()),
                        typeof(void)
                        );
                }
            }

            if (parameterBinder.Temps != null)
            {
                ret = Ast.Block(parameterBinder.Temps, ret);
            }

            return(ret);
        }