Exemplo n.º 1
0
        private MetaObject MakeMethodIndexRule(string oper, MetaObject[] args)
        {
            MethodInfo[] defaults = GetMethodsFromDefaults(args[0].LimitType.GetDefaultMembers(), oper);
            if (defaults.Length != 0)
            {
                MethodBinder binder = MethodBinder.MakeBinder(
                    this,
                    oper == StandardOperators.GetItem ? "get_Item" : "set_Item",
                    defaults);

                MetaObject[]        selfWithArgs = args;
                ParameterExpression arg2         = null;

                if (oper == StandardOperators.SetItem)
                {
                    Debug.Assert(args.Length >= 2);

                    // need to save arg2 in a temp because it's also our result
                    arg2 = Ast.Variable(args[2].Expression.Type, "arg2Temp");

                    args[2] = new MetaObject(
                        Ast.Assign(arg2, args[2].Expression),
                        args[2].Restrictions
                        );
                }

                BindingTarget target = binder.MakeBindingTarget(CallTypes.ImplicitInstance, selfWithArgs);

                Restrictions restrictions = Restrictions.Combine(args);

                if (target.Success)
                {
                    if (oper == StandardOperators.GetItem)
                    {
                        return(new MetaObject(
                                   target.MakeExpression(),
                                   restrictions.Merge(Restrictions.Combine(target.RestrictedArguments))
                                   ));
                    }
                    else
                    {
                        return(new MetaObject(
                                   Ast.Block(
                                       new ParameterExpression[] { arg2 },
                                       target.MakeExpression(),
                                       arg2
                                       ),
                                   restrictions.Merge(Restrictions.Combine(target.RestrictedArguments))
                                   ));
                    }
                }

                return(MakeError(
                           MakeInvalidParametersError(target),
                           restrictions
                           ));
            }

            return(null);
        }
Exemplo n.º 2
0
        private MetaObject TryMakeBindingTarget(MethodInfo[] targets, MetaObject[] args, Expression codeContext, Restrictions restrictions)
        {
            MethodBinder mb = MethodBinder.MakeBinder(this, targets[0].Name, targets);

            BindingTarget target = mb.MakeBindingTarget(CallTypes.None, args);

            if (target.Success)
            {
                return(new MetaObject(
                           target.MakeExpression(new ParameterBinderWithCodeContext(this, codeContext)),
                           restrictions.Merge(Restrictions.Combine(target.RestrictedArguments))
                           ));
            }

            return(null);
        }
Exemplo n.º 3
0
        private MetaObject TryMakeInvertedBindingTarget(MethodBase[] targets, MetaObject[] args)
        {
            MethodBinder mb = MethodBinder.MakeBinder(this, targets[0].Name, targets);

            MetaObject[]  selfArgs = args;
            BindingTarget target   = mb.MakeBindingTarget(CallTypes.None, selfArgs);

            if (target.Success)
            {
                return(new MetaObject(
                           Ast.Not(target.MakeExpression()),
                           Restrictions.Combine(target.RestrictedArguments)
                           ));
            }

            return(null);
        }
Exemplo n.º 4
0
        private MetaObject TryNumericComparison(OperatorInfo info, MetaObject[] args)
        {
            MethodInfo[] targets = FilterNonMethods(
                args[0].LimitType,
                GetMember(OldDoOperationAction.Make(this, info.Operator),
                          args[0].LimitType,
                          "Compare")
                );

            if (targets.Length > 0)
            {
                MethodBinder  mb     = MethodBinder.MakeBinder(this, targets[0].Name, targets);
                BindingTarget target = mb.MakeBindingTarget(CallTypes.None, args);
                if (target.Success)
                {
                    Expression call = AstUtils.Convert(target.MakeExpression(), typeof(int));
                    switch (info.Operator)
                    {
                    case Operators.GreaterThan: call = Ast.GreaterThan(call, Ast.Constant(0)); break;

                    case Operators.LessThan: call = Ast.LessThan(call, Ast.Constant(0)); break;

                    case Operators.GreaterThanOrEqual: call = Ast.GreaterThanOrEqual(call, Ast.Constant(0)); break;

                    case Operators.LessThanOrEqual: call = Ast.LessThanOrEqual(call, Ast.Constant(0)); break;

                    case Operators.Equals: call = Ast.Equal(call, Ast.Constant(0)); break;

                    case Operators.NotEquals: call = Ast.NotEqual(call, Ast.Constant(0)); break;

                    case Operators.Compare:
                        break;
                    }

                    return(new MetaObject(
                               call,
                               Restrictions.Combine(target.RestrictedArguments)
                               ));
                }
            }

            return(null);
        }
Exemplo n.º 5
0
        private MetaObject CallWorker(ParameterBinder parameterBinder, IList <MethodBase> targets, IList <MetaObject> args, CallSignature signature, CallTypes callType, Restrictions restrictions, NarrowingLevel minLevel, NarrowingLevel maxLevel, string name, out BindingTarget target)
        {
            ContractUtils.RequiresNotNull(parameterBinder, "parameterBinder");
            ContractUtils.RequiresNotNullItems(args, "args");
            ContractUtils.RequiresNotNullItems(targets, "targets");
            ContractUtils.RequiresNotNull(restrictions, "restrictions");

            MetaObject[] finalArgs;
            SymbolId[]   argNames;

            if (callType == CallTypes.ImplicitInstance)
            {
                GetArgumentNamesAndTypes(signature, ArrayUtils.RemoveFirst(args), out argNames, out finalArgs);
                finalArgs = ArrayUtils.Insert(args[0], finalArgs);
            }
            else
            {
                GetArgumentNamesAndTypes(signature, args, out argNames, out finalArgs);
            }

            // attempt to bind to an individual method
            MethodBinder binder = MethodBinder.MakeBinder(
                this,
                name ?? GetTargetName(targets),
                targets,
                argNames,
                minLevel,
                maxLevel);

            target = binder.MakeBindingTarget(callType, finalArgs);

            if (target.Success)
            {
                // if we succeed make the target for the rule
                return(new MetaObject(
                           target.MakeExpression(parameterBinder),
                           restrictions.Merge(MakeSplatTests(callType, signature, args).Merge(Restrictions.Combine(target.RestrictedArguments)))
                           ));
            }
            // make an error rule
            return(MakeInvalidParametersRule(callType, signature, this, args, restrictions, target));
        }
        private bool MakeDefaultMemberRule(Operators oper)
        {
            if (_types[0].IsArray)
            {
                if (Binder.CanConvertFrom(_types[1], typeof(int), NarrowingLevel.All))
                {
                    if (oper == Operators.GetItem)
                    {
                        _rule.SetTarget(_rule.MakeReturn(Binder,
                                                         Ast.ArrayIndex(
                                                             Param0,
                                                             ConvertIfNeeded(Param1, typeof(int))
                                                             )
                                                         ));
                    }
                    else
                    {
                        _rule.SetTarget(_rule.MakeReturn(Binder,
                                                         Ast.AssignArrayIndex(
                                                             Param0,
                                                             ConvertIfNeeded(Param1, typeof(int)),
                                                             ConvertIfNeeded(Param2, _types[0].GetElementType())
                                                             )
                                                         ));
                    }
                    return(true);
                }
            }

            MethodInfo[] defaults = GetMethodsFromDefaults(_types[0].GetDefaultMembers(), oper);
            if (defaults.Length != 0)
            {
                MethodBinder binder = MethodBinder.MakeBinder(Binder,
                                                              oper == Operators.GetItem ? "get_Item" : "set_Item",
                                                              defaults,
                                                              BinderType.Normal);

                MethodCandidate cand = binder.MakeBindingTarget(CallType.ImplicitInstance, _types);

                if (cand != null)
                {
                    if (oper == Operators.GetItem)
                    {
                        _rule.SetTarget(_rule.MakeReturn(Binder, cand.Target.MakeExpression(Binder, _rule, _rule.Parameters, _types)));
                    }
                    else
                    {
                        _rule.SetTarget(_rule.MakeReturn(Binder,
                                                         Ast.Comma(0,
                                                                   _rule.Parameters[2],
                                                                   cand.Target.MakeExpression(Binder, _rule, _rule.Parameters, _types)
                                                                   )
                                                         ));
                    }
                }
                else
                {
                    _rule.SetTarget(Binder.MakeInvalidParametersError(binder, Action, CallType.None, defaults, _rule, _args));
                }
                return(true);
            }

            return(false);
        }
Exemplo n.º 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);
            }
        }