public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            if (target.HasValue && target.Value == null)
            {
                return(errorSuggestion ??
                       new DynamicMetaObject(
                           Expression.Throw(
                               Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }),
                                              Expression.Constant(String.Format("Cannot call {0} method named {1} on nil", _isStatic ? "static" : "instance", this.Name))),
                               typeof(object)),
                           BindingRestrictions.GetInstanceRestriction(target.Expression, null)));
            }



            Type typeToUse = _isStatic && target.Value is Type ? (Type)target.Value : target.LimitType;


            IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(args.Length + (_isStatic ? 0 : 1));

            if (!_isStatic)
            {
                argsPlus.Add(target);
            }
            foreach (DynamicMetaObject arg in args)
            {
                argsPlus.Add(arg);
            }

            OverloadResolverFactory factory = _context.SharedOverloadResolverFactory;
            DefaultOverloadResolver res     = factory.CreateOverloadResolver(argsPlus, new CallSignature(args.Length), _isStatic ? CallTypes.None : CallTypes.ImplicitInstance);

            BindingFlags       flags   = BindingFlags.InvokeMethod | BindingFlags.Public | (_isStatic ? BindingFlags.Static : BindingFlags.Instance);
            IList <MethodBase> methods = new List <MethodBase>(typeToUse.GetMethods(flags).Where <MethodBase>(x => x.Name == Name && x.GetParameters().Length == args.Length));

            if (methods.Count > 0)
            {
                BindingTarget     bt;
                DynamicMetaObject dmo = _context.Binder.CallMethod(
                    res,
                    methods,
                    target.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target).Merge(BindingRestrictions.Combine(args))),
                    Name,
                    NarrowingLevel.None,
                    NarrowingLevel.All,
                    out bt);
                dmo = DynUtils.MaybeBoxReturnValue(dmo);

                //; Console.WriteLine(dmo.Expression.DebugView);
                return(dmo);
            }

            return(errorSuggestion ??
                   new DynamicMetaObject(
                       Expression.Throw(
                           Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }),
                                          Expression.Constant(String.Format("No matching member {0} taking {1} args for {2}", this.Name, args.Length, typeToUse.Name))),
                           typeof(object)),
                       target.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target).Merge(BindingRestrictions.Combine(args)))));
        }
        public override DynamicMetaObject FallbackCreateInstance(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            Type typeToUse = target.Value is Type ? (Type)target.Value : target.LimitType;

            IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(args.Length);

            foreach (DynamicMetaObject arg in args)
            {
                argsPlus.Add(arg);
            }

            OverloadResolverFactory factory = _context.SharedOverloadResolverFactory;
            DefaultOverloadResolver res     = factory.CreateOverloadResolver(argsPlus, new CallSignature(args.Length), CallTypes.None);

            BindingFlags       flags   = BindingFlags.Public | BindingFlags.Instance;
            IList <MethodBase> methods = new List <MethodBase>(typeToUse.GetConstructors(flags).Where <MethodBase>(x => x.GetParameters().Length == args.Length));

            if (methods.Count > 0)
            {
                BindingTarget     bt;
                DynamicMetaObject dmo = _context.Binder.CallMethod(res, methods, BindingRestrictions.Empty, "_ctor", NarrowingLevel.None, NarrowingLevel.All, out bt);
                dmo = DynUtils.MaybeBoxReturnValue(dmo);
                return(dmo);
            }

            return(errorSuggestion ??
                   new DynamicMetaObject(
                       Expression.Throw(
                           Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }),
                                          Expression.Constant("Cannot find constructor matching args")),
                           typeof(object)),
                       target.Restrictions.Merge(BindingRestrictions.Combine(args))));
        }
Exemplo n.º 3
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:
                    t = typeof(System.Runtime.CompilerServices.StrongBox <>).MakeGenericType(argType);
                    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);
        }
Exemplo n.º 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);
        }
Exemplo n.º 5
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);
        }