Ejemplo 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);
        }
Ejemplo n.º 2
0
        private DynamicMetaObject MakeMethodIndexRule(IndexType oper, OverloadResolverFactory resolverFactory, DynamicMetaObject[] args)
        {
            MethodInfo[] defaults = GetMethodsFromDefaults(args[0].GetLimitType().GetDefaultMembers(), oper);
            if (defaults.Length != 0)
            {
                DynamicMetaObject[] selfWithArgs = args;
                ParameterExpression arg2         = null;

                if (oper == IndexType.Set)
                {
                    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 DynamicMetaObject(
                        Ast.Assign(arg2, args[2].Expression),
                        args[2].Restrictions
                        );
                }

                BindingRestrictions restrictions = BindingRestrictions.Combine(args);

                var           resolver = resolverFactory.CreateOverloadResolver(selfWithArgs, new CallSignature(selfWithArgs.Length), CallTypes.ImplicitInstance);
                BindingTarget target   = resolver.ResolveOverload(oper == IndexType.Get ? "get_Item" : "set_Item", defaults, NarrowingLevel.None, NarrowingLevel.All);
                if (target.Success)
                {
                    if (oper == IndexType.Get)
                    {
                        return(new DynamicMetaObject(
                                   target.MakeExpression(),
                                   restrictions.Merge(target.RestrictedArguments.GetAllRestrictions())
                                   ));
                    }
                    else
                    {
                        return(new DynamicMetaObject(
                                   Ast.Block(
                                       new ParameterExpression[] { arg2 },
                                       target.MakeExpression(),
                                       arg2
                                       ),
                                   restrictions.Merge(target.RestrictedArguments.GetAllRestrictions())
                                   ));
                    }
                }

                return(MakeError(
                           resolver.MakeInvalidParametersError(target),
                           restrictions,
                           typeof(object)
                           ));
            }

            return(null);
        }
Ejemplo n.º 3
0
        public DynamicMetaObject MakeCallExpression(OverloadResolverFactory resolverFactory, MethodInfo method, params DynamicMetaObject[] parameters)
        {
            OverloadResolver resolver;

            if (method.IsStatic)
            {
                resolver = resolverFactory.CreateOverloadResolver(parameters, new CallSignature(parameters.Length), CallTypes.None);
            }
            else
            {
                resolver = resolverFactory.CreateOverloadResolver(parameters, new CallSignature(parameters.Length - 1), CallTypes.ImplicitInstance);
            }
            BindingTarget target = resolver.ResolveOverload(method.Name, new MethodBase[] { method }, NarrowingLevel.None, NarrowingLevel.All);

            if (!target.Success)
            {
                BindingRestrictions restrictions = BindingRestrictions.Combine(parameters);
                foreach (DynamicMetaObject mo in parameters)
                {
                    restrictions = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(mo.Expression, mo.GetLimitType()));
                }
                return(DefaultBinder.MakeError(
                           resolver.MakeInvalidParametersError(target),
                           restrictions,
                           typeof(object)
                           ));
            }

            return(new DynamicMetaObject(target.MakeExpression(), target.RestrictedArguments.GetAllRestrictions()));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Performs binding against a set of overloaded methods using the specified arguments.  The arguments are
        /// consumed as specified by the CallSignature object.
        /// </summary>
        /// <param name="minLevel">TODO.</param>
        /// <param name="maxLevel">TODO.</param>
        /// <param name="resolver">Overload resolver.</param>
        /// <param name="targets">The methods to be called</param>
        /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param>
        /// <param name="target">The resulting binding target which can be used for producing error information.</param>
        /// <param name="name">The name of the method or null to use the name from targets.</param>
        /// <returns>A meta object which results from the call.</returns>
        public DynamicMetaObject CallMethod(DefaultOverloadResolver resolver, IList <MethodBase> targets, BindingRestrictions restrictions, string name,
                                            NarrowingLevel minLevel, NarrowingLevel maxLevel, out BindingTarget target)
        {
            ContractUtils.RequiresNotNull(resolver, nameof(resolver));
            ContractUtils.RequiresNotNullItems(targets, nameof(targets));
            ContractUtils.RequiresNotNull(restrictions, nameof(restrictions));

            // attempt to bind to an individual method
            target = resolver.ResolveOverload(name ?? GetTargetName(targets), targets, minLevel, maxLevel);

            if (target.Success)
            {
                // if we succeed make the target for the rule
                return(new DynamicMetaObject(
                           target.MakeExpression(),
                           restrictions.Merge(
                               MakeSplatTests(resolver.CallType, resolver.Signature, resolver.Arguments).
                               Merge(target.RestrictedArguments.GetAllRestrictions())
                               )
                           ));
            }

            // make an error rule
            return(MakeInvalidParametersRule(resolver, restrictions, target));
        }
Ejemplo n.º 5
0
        private bool TryNumericComparison(OperatorInfo info)
        {
            MethodInfo[] targets = FilterNonMethods(_types[0], Binder.GetMember(Action, _types[0], "Compare"));
            if (targets.Length > 0)
            {
                MethodBinder  mb     = MethodBinder.MakeBinder(Binder, targets[0].Name, targets);
                BindingTarget target = mb.MakeBindingTarget(CallTypes.None, _types);
                if (target.Success)
                {
                    Expression call = Ast.Convert(target.MakeExpression(_rule, _rule.Parameters), 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;
                    }
                    _rule.Target = _rule.MakeReturn(Binder, call);
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 6
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);
            }
        }
Ejemplo n.º 7
0
        private bool TryMakeInvertedBindingTarget(MethodInfo[] targets)
        {
            MethodBinder  mb     = MethodBinder.MakeBinder(Binder, targets[0].Name, targets);
            BindingTarget target = mb.MakeBindingTarget(CallTypes.None, _types);

            if (target.Success)
            {
                Expression call = target.MakeExpression(_rule, _rule.Parameters);
                _rule.Target = _rule.MakeReturn(Binder, Ast.Not(call));
                return(true);
            }
            return(false);
        }
Ejemplo n.º 8
0
        private DynamicMetaObject TryMakeInvertedBindingTarget(OverloadResolverFactory resolverFactory, MethodBase[] targets, DynamicMetaObject[] args)
        {
            var           resolver = resolverFactory.CreateOverloadResolver(args, new CallSignature(args.Length), CallTypes.None);
            BindingTarget target   = resolver.ResolveOverload(targets[0].Name, targets, NarrowingLevel.None, NarrowingLevel.All);

            if (target.Success)
            {
                return(new DynamicMetaObject(
                           Expression.Not(target.MakeExpression()),
                           target.RestrictedArguments.GetAllRestrictions()
                           ));
            }

            return(null);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
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);
        }
Ejemplo n.º 12
0
        private DynamicMetaObject TryNumericComparison(OperatorInfo info, OverloadResolverFactory resolverFactory, DynamicMetaObject[] args)
        {
            MethodInfo[] targets = FilterNonMethods(
                args[0].GetLimitType(),
                GetMember(
                    MemberRequestKind.Operation,
                    args[0].GetLimitType(),
                    "Compare"
                    )
                );

            if (targets.Length > 0)
            {
                var           resolver = resolverFactory.CreateOverloadResolver(args, new CallSignature(args.Length), CallTypes.None);
                BindingTarget target   = resolver.ResolveOverload(targets[0].Name, targets, NarrowingLevel.None, NarrowingLevel.All);
                if (target.Success)
                {
                    Expression call = AstUtils.Convert(target.MakeExpression(), typeof(int));
                    switch (info.Operator)
                    {
                    case ExpressionType.GreaterThan: call = Expression.GreaterThan(call, AstUtils.Constant(0)); break;

                    case ExpressionType.LessThan: call = Expression.LessThan(call, AstUtils.Constant(0)); break;

                    case ExpressionType.GreaterThanOrEqual: call = Expression.GreaterThanOrEqual(call, AstUtils.Constant(0)); break;

                    case ExpressionType.LessThanOrEqual: call = Expression.LessThanOrEqual(call, AstUtils.Constant(0)); break;

                    case ExpressionType.Equal: call = Expression.Equal(call, AstUtils.Constant(0)); break;

                    case ExpressionType.NotEqual: call = Expression.NotEqual(call, AstUtils.Constant(0)); break;
                    }

                    return(new DynamicMetaObject(
                               call,
                               target.RestrictedArguments.GetAllRestrictions()
                               ));
                }
            }

            return(null);
        }
Ejemplo n.º 13
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));
        }
Ejemplo n.º 14
0
        private bool MakeDefaultMemberRule(Operators oper)
        {
            if (_types[0].IsArray)
            {
                if (Binder.CanConvertFrom(_types[1], typeof(int), false, NarrowingLevel.All))
                {
                    if (oper == Operators.GetItem)
                    {
                        _rule.Target = _rule.MakeReturn(Binder,
                                                        Ast.ArrayAccess(
                                                            Param0,
                                                            ConvertIfNeeded(Param1, typeof(int))
                                                            )
                                                        );
                    }
                    else
                    {
                        _rule.Target = _rule.MakeReturn(Binder,
                                                        Ast.Assign(
                                                            Ast.ArrayAccess(
                                                                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);

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

                if (target.Success)
                {
                    if (oper == Operators.GetItem)
                    {
                        _rule.Target = _rule.MakeReturn(Binder, target.MakeExpression(_rule, _rule.Parameters));
                    }
                    else
                    {
                        _rule.Target = _rule.MakeReturn(Binder,
                                                        Ast.Block(
                                                            target.MakeExpression(_rule, _rule.Parameters),
                                                            _rule.Parameters[2]
                                                            )
                                                        );
                    }
                }
                else
                {
                    _rule.Target = Binder.MakeInvalidParametersError(target).MakeErrorForRule(_rule, Binder);
                }
                return(true);
            }

            return(false);
        }
Ejemplo n.º 15
0
        protected Expression GenDlrForMethod(ObjExpr objx, GenContext context)
        {
            if (_method.DeclaringType == (Type)Compiler.CompileStubOrigClassVar.deref())
            {
                _method = FindEquivalentMethod(_method, objx.BaseType);
            }

            int argCount = _args.Count;


            IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(argCount + (IsStaticCall ? 0 : 1));

            if (!IsStaticCall)
            {
                argsPlus.Add(new DynamicMetaObject(Expression.Convert(GenTargetExpression(objx, context), _method.DeclaringType), BindingRestrictions.Empty));
            }

            List <int> refPositions = new List <int>();

            ParameterInfo[] methodParms = _method.GetParameters();

            for (int i = 0; i < argCount; i++)
            {
                HostArg ha = _args[i];

                Expr e       = ha.ArgExpr;
                Type argType = e.HasClrType ? (e.ClrType ?? typeof(object)) : typeof(Object);

                //Type t;

                switch (ha.ParamType)
                {
                case HostArg.ParameterType.ByRef:
                    refPositions.Add(i);
                    argsPlus.Add(new DynamicMetaObject(HostExpr.GenUnboxArg(GenTypedArg(objx, context, argType, e), methodParms[i].ParameterType.GetElementType()), BindingRestrictions.Empty));
                    break;

                case HostArg.ParameterType.Standard:
                    Type ptype = methodParms[i].ParameterType;
                    if (ptype.IsGenericParameter)
                    {
                        ptype = argType;
                    }

                    Expression typedArg = GenTypedArg(objx, context, ptype, e);

                    argsPlus.Add(new DynamicMetaObject(typedArg, BindingRestrictions.Empty));

                    break;

                default:
                    throw Util.UnreachableCode();
                }
            }

            // TODO: get rid of use of Default
            OverloadResolverFactory factory = ClojureContext.Default.SharedOverloadResolverFactory;
            DefaultOverloadResolver res     = factory.CreateOverloadResolver(argsPlus, new CallSignature(argCount), IsStaticCall ? CallTypes.None : CallTypes.ImplicitInstance);

            List <MethodBase> methods = new List <MethodBase>();

            methods.Add(_method);

            BindingTarget bt = res.ResolveOverload(_methodName, methods, NarrowingLevel.None, NarrowingLevel.All);

            if (!bt.Success)
            {
                throw new ArgumentException("Conflict in argument matching. -- Internal error.");
            }

            Expression call = bt.MakeExpression();

            if (refPositions.Count > 0)
            {
                ParameterExpression resultParm = Expression.Parameter(typeof(Object[]));

                List <Expression> stmts = new List <Expression>(refPositions.Count + 2);
                stmts.Add(Expression.Assign(resultParm, call));

                // TODO: Fold this into the loop above
                foreach (int i in refPositions)
                {
                    HostArg ha      = _args[i];
                    Expr    e       = ha.ArgExpr;
                    Type    argType = e.HasClrType ? (e.ClrType ?? typeof(object)) : typeof(Object);
                    stmts.Add(Expression.Assign(_args[i].LocalBinding.ParamExpression, Expression.Convert(Expression.ArrayIndex(resultParm, Expression.Constant(i + 1)), argType)));
                }

                Type returnType = HasClrType ? ClrType : typeof(object);
                stmts.Add(Expression.Convert(Expression.ArrayIndex(resultParm, Expression.Constant(0)), returnType));
                call = Expression.Block(new ParameterExpression[] { resultParm }, stmts);
            }

            call = _arithmeticRewriter.Visit(call);

            return(call);
        }