private DynamicMetaObject TryMakeBindingTarget(OverloadResolverFactory resolverFactory, MethodInfo[] targets, DynamicMetaObject[] args, BindingRestrictions restrictions)
        {
            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(
                           target.MakeExpression(),
                           restrictions.Merge(target.RestrictedArguments.GetAllRestrictions())
                           ));
            }

            return(null);
        }
示例#2
0
        private DynamicMetaObject MakeMetaMethodCall(CallSignature signature, OverloadResolverFactory resolverFactory, TargetInfo targetInfo) {
            BindingRestrictions restrictions = BindingRestrictions.Combine(targetInfo.Arguments).Merge(targetInfo.Restrictions);
            if (targetInfo.Instance != null) {
                restrictions = targetInfo.Instance.Restrictions.Merge(restrictions);
            }

            DynamicMetaObject[] args;
            CallTypes callType;
            if (targetInfo.Instance != null) {
                args = ArrayUtils.Insert(targetInfo.Instance, targetInfo.Arguments);
                callType = CallTypes.ImplicitInstance;
            } else {
                args = targetInfo.Arguments;
                callType = CallTypes.None;
            }

            return CallMethod(resolverFactory.CreateOverloadResolver(args, signature, callType), targetInfo.Targets, restrictions);
        }
示例#3
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);
        }
示例#4
0
        private static MethodBase GetMatchingMethodAux(Type targetType, object[] actualArgs, IList <MethodBase> methods, string methodName, bool isStatic)
        {
            int argCount = actualArgs.Length;

            if (methods.Count == 0)
            {
                return(null);
            }

            if (methods.Count == 1)
            {
                return(methods[0]);
            }

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

            if (!isStatic)
            {
                argsPlus.Add(new DynamicMetaObject(Expression.Default(targetType), BindingRestrictions.Empty));
            }

            foreach (object arg in actualArgs)
            {
                argsPlus.Add(new DynamicMetaObject(Expression.Default(arg.GetType()), BindingRestrictions.Empty, arg));
            }

            OverloadResolverFactory factory = ClojureContext.Default.SharedOverloadResolverFactory;
            DefaultOverloadResolver res     = factory.CreateOverloadResolver(argsPlus, new CallSignature(argCount), isStatic ? CallTypes.None : CallTypes.ImplicitInstance);

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

            if (bt.Success)
            {
                return(bt.Overload.ReflectionInfo);
            }

            return(null);
        }
示例#5
0
        /// <summary>
        /// Select matching method from list based on args.
        /// </summary>
        /// <param name="targetType"></param>
        /// <param name="args"></param>
        /// <param name="methods"></param>
        /// <param name="methodName"></param>
        /// <param name="isStatic"></param>
        /// <returns></returns>
        private static MethodBase GetMatchingMethodAux(Type targetType, IList <HostArg> args, IList <MethodBase> methods, string methodName, bool isStatic)
        {
            int argCount = args.Count;

            if (methods.Count == 0)
            {
                return(null);
            }

            if (methods.Count == 1)
            {
                return(methods[0]);
            }

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

            if (!isStatic)
            {
                argsPlus.Add(new DynamicMetaObject(Expression.Default(targetType), BindingRestrictions.Empty));
            }

            foreach (HostArg ha in args)
            {
                Expr e       = ha.ArgExpr;
                Type argType = e.HasClrType ? (e.ClrType ?? typeof(object)) : typeof(Object);

                Type t;

                switch (ha.ParamType)
                {
                case HostArg.ParameterType.ByRef:
#if CLR2
                    t = typeof(MSC::System.Runtime.CompilerServices.StrongBox <>).MakeGenericType(argType);
#else
                    t = typeof(System.Runtime.CompilerServices.StrongBox <>).MakeGenericType(argType);
#endif

                    break;

                case HostArg.ParameterType.Standard:
                    t = argType;
                    break;

                default:
                    throw Util.UnreachableCode();
                }
                argsPlus.Add(new DynamicMetaObject(Expression.Default(t), BindingRestrictions.Empty));
            }

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

            BindingTarget bt = res.ResolveOverload(methodName, methods, NarrowingLevel.None, NarrowingLevel.All);
            if (bt.Success)
            {
                return(bt.Overload.ReflectionInfo);
            }

            return(null);
        }
示例#6
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);
        }