public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
            {
                Type[] argTypes = args.Select(a => a.RuntimeType).ToArray();
                MethodInfo method = type.GetMethod(binder.Name, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public, null, argTypes, null);

                if (method == null)
                    return base.BindInvokeMember(binder, args);

                var parameters = new Expression[] { Expression.Constant(null), Expression.NewArrayInit(typeof(object), args.Select(a => Expression.Convert(a.Expression, typeof(object)))) };

                return new DynamicMetaObject(
                    Expression.Call(
                        Expression.Constant(method),
                        typeof(MethodInfo).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) }),
                        parameters),
                    BindingRestrictions.GetTypeRestriction(Expression, LimitType));
            }
示例#2
0
 public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)
 {
     return new DynamicMetaObject(
         Expression.Call(
             Expression.Constant(Function),
             typeof(BonsaiFunction).GetMethod("Call"),
             Expression.NewArrayInit(typeof(object), args.Select(a => Expression.Convert(a.Expression, typeof(object))))),
         BindingRestrictions.GetInstanceRestriction(this.Expression, Function));
 }
示例#3
0
        public static Expr Call(Expr context, DynamicMetaObject target, DynamicMetaObject[] args)
        {
            var expression = Expr.Invoke(
                Expr.Constant((Func<CodeContext, object, object[], object>)LuaOps.CallMetamethod),
                context,
                Expr.Convert(target.Expression, typeof(object)),
                Expr.NewArrayInit(
                    typeof(object),
                    args.Select(arg => Expr.Convert(arg.Expression, typeof(object)))));

            return expression;
        }
示例#4
0
        public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            var combinedArgs = new Expr[args.Length + 1];
            combinedArgs[0] = target.Expression;
            Array.Copy(args.Select(a => a.Expression).ToArray(), 0, combinedArgs, 1, args.Length);

            var restrictions = target.Restrictions.Merge(BindingRestrictions.Combine(args));
            var expression =
                Expr.Dynamic(
                    context.CreateInvokeBinder(new CallInfo(args.Length)),
                    typeof(object),
                    combinedArgs);

            return new DynamicMetaObject(expression, restrictions);
        }
示例#5
0
        public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
        {
            var limitedSelf = Expression;
            if (limitedSelf.Type != LimitType)
            {
                limitedSelf = Expression.Convert(limitedSelf, LimitType);
            }

            var indexer = LimitType.GetProperty("Item");
            Expression expression = Expression.Call(limitedSelf, indexer.GetGetMethod(), indexes.Select(i => i.Expression));
            if (binder.ReturnType != expression.Type)
            {
                expression = Expression.Convert(expression, binder.ReturnType);
            }

            return new DynamicMetaObject(expression, BindingRestrictions.GetTypeRestriction(Expression, LimitType));
        }
        public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            var combinedArgs = new Expr[args.Length + 1];
            combinedArgs[0] = target.Expression;
            Array.Copy(args.Select(a => a.Expression).ToArray(), 0, combinedArgs, 1, args.Length);

            var restrictions = target.Restrictions.Merge(BindingRestrictions.Combine(args));
            Expr expression =
                Expr.Dynamic(
                    context.CreateInvokeBinder(new CallInfo(args.Length)),
                    typeof(object),
                    combinedArgs);

            expression = MetamethodFallbacks.WrapStackTrace(expression, context,
                    new FunctionStack(context,null, null, context.CurrentVariableIdentifier + "." + Name));

            return new DynamicMetaObject(expression, restrictions);
        }
示例#7
0
        // Return the expression for getting target[indexes]
        //
        // Note, callers must ensure consistent restrictions are added for
        // the conversions on args and target.
        //
        public static Expression GetIndexingExpression(
            DynamicMetaObject target,
            DynamicMetaObject[] indexes)
        {
            Debug.Assert(target.HasValue && target.LimitType != typeof(Array));

            var indexExpressions = indexes.Select(
                i => Expression.Convert(i.Expression, i.LimitType))
                .ToArray();

            //// CONS
            //if (target.LimitType == typeof(Cons))
            //{
            //    // Call RuntimeHelper.GetConsElt
            //    var args = new List<Expression>();
            //    // The first argument is the list
            //    args.Add(
            //        Expression.Convert(
            //            target.Expression,
            //            target.LimitType)
            //    );
            //    args.AddRange(indexExpressions);
            //    return Expression.Call(
            //        typeof(RuntimeHelpers),
            //        "GetConsElt",
            //        null,
            //        args.ToArray());
            //    // ARRAY
            //}
            //else
            if (target.LimitType.IsArray)
            {
                return Expression.ArrayAccess(
                    Expression.Convert(target.Expression,
                        target.LimitType),
                    indexExpressions
                    );
                // INDEXER
            }
            else
            {
                var props = target.LimitType.GetProperties();
                var indexers = props.Where(p => p.GetIndexParameters().Length > 0).ToArray();
                indexers = indexers.Where(idx => idx.GetIndexParameters().Length == indexes.Length).ToArray();

                var res = new List<PropertyInfo>();
                foreach (var idxer in indexers)
                {
                    if (RuntimeHelpers.ParametersMatchArguments(
                        idxer.GetIndexParameters(), indexes))
                    {
                        // all parameter types match
                        res.Add(idxer);
                    }
                }
                if (res.Count == 0)
                {
                    return Expression.Throw(
                        Expression.New(
                            typeof(MissingMemberException)
                                .GetConstructor(new Type[] { typeof(string) }),
                            Expression.Constant(
                                "Can't bind because there is no matching indexer.")
                            )
                        );
                }
                return Expression.MakeIndex(
                    Expression.Convert(target.Expression, target.LimitType),
                    res[0], indexExpressions);
            }
        }
		public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
		{
			var wrapper = this.Value as ExpressionContainer;
			var valueExpr = wrapper.Expression;

			var typeArgs = MockingUtil.TryGetTypeArgumentsFromBinder(binder);

			var candidateMethods = valueExpr.Type.GetAllMethods()
				.Where(m => MockingUtil.StringEqual(m.Name, binder.Name, binder.IgnoreCase) && m.IsStatic == wrapper.IsStatic)
				.Where(m => m.GetParameters().Length >= args.Length)
				.Select(m =>
				{
					if (typeArgs == null)
					{
						return MockingUtil.TrySpecializeGenericMethod(m, args.Select(a => a.RuntimeType).ToArray()) ?? m;
					}
					else
					{
						return MockingUtil.TryApplyTypeArguments(m, typeArgs);
					}
				})
				.Where(m => m != null)
				.Where(m =>
				{
					var methodParams = m.GetParameters();
					for (int i = 0; i < args.Length; ++i)
					{
						var matcher = UnwrapMatcher(args[i]);
						if (matcher != null)
						{
							var argType = matcher.ReturnType;
							if (!methodParams[i].ParameterType.IsAssignableFrom(argType))
								return false;
						}
					}
					return true;
				})
				.ToArray();

			if (candidateMethods.Length == 0 && args.Length == 0)
			{
				return DoBindGetMember(binder.ReturnType, binder.Name, binder.IgnoreCase);
			}

			var methodArgs = args.Select(a =>
			{
				var matcher = UnwrapMatcher(a);
				return matcher != null ? matcher.ReturnType.GetDefaultValue() : a.Value;
			}).ToArray();

			object state;
			var method = (MethodInfo)MockingUtil.BindToMethod(MockingUtil.Default, candidateMethods, ref methodArgs, null, null, null, out state);

			var memberExpr = Expression.Call(!wrapper.IsStatic ? valueExpr : null, method, args.Select(FromArg).ToArray());

			return CreateRecorder(memberExpr, binder.ReturnType);
		}
		public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
		{
			var wrapper = this.Value as ExpressionContainer;
			var valueExpr = wrapper.Expression;
			var property = PrivateAccessor.ResolveProperty(valueExpr.Type, "Item", false,
				indexes.Select(i => i.Value).ToArray(), !wrapper.IsStatic, value.Value, getter: false);
			if (property == null)
				ThrowMissingMemberException(valueExpr.Type, "Item");

			var memberExpr = Expression.Assign(
				Expression.MakeIndex(!wrapper.IsStatic ? valueExpr : null, property, indexes.Select(FromArg)),
				FromArg(value));
			return CreateRecorder(memberExpr, binder.ReturnType);
		}
示例#10
0
			public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
			{
				return BindSetMember(binder.ReturnType, "Item", value.Expression, indexes.Select(i => i.Expression));
			}
示例#11
0
			public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
			{
				var getProp = typeof(PrivateAccessor).GetMethod("GetProperty");

				var call = Expression.Call(Expression.Convert(this.Expression, typeof(PrivateAccessor)), getProp,
					Expression.Constant("Item"),
					Expression.NewArrayInit(typeof(object), indexes.Select(a => Expression.Convert(a.Expression, typeof(object)))));
				return CreateMetaObject(call);
			}
示例#12
0
			public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
			{
				var callResult = Expression.Variable(typeof(object));
				var argsVar = Expression.Variable(typeof(object[]));

				MethodInfo invoke = typeof(PrivateAccessor).GetMethod("CallMethod", new[] { typeof(string), typeof(object[]) });
				var invokeArgs = new List<Expression>
				{
					Expression.Constant(binder.Name),
					argsVar
				};

				var typeArgs = MockingUtil.TryGetTypeArgumentsFromBinder(binder);
				if (typeArgs != null)
				{
					invoke = typeof(PrivateAccessor).GetMethod("CallMethodWithTypeArguments");
					invokeArgs.Insert(1, Expression.Constant(typeArgs));
				}

				var executionList = new List<Expression>
				{
					Expression.Assign(argsVar, Expression.NewArrayInit(typeof(object), args.Select(a => Expression.Convert(a.Expression, typeof(object))))),
					Expression.Assign(callResult, Expression.Call(
						Expression.Convert(this.Expression, typeof(PrivateAccessor)), invoke, invokeArgs.ToArray())),
				};

				executionList.AddRange(args
					.Select((a, i) => new { expr = a.Expression, i })
					.Where(p => p.expr is ParameterExpression)
					.Select(p => Expression.Assign(p.expr, Expression.Convert(Expression.ArrayIndex(argsVar, Expression.Constant(p.i)), p.expr.Type))));
				executionList.Add(callResult);

				return CreateMetaObject(Expression.Block(new[] { argsVar, callResult }, executionList));
			}
示例#13
0
        IEnumerable<Expr> MapArguments(DynamicMetaObject[] args, MethodInfo methodInfo, ref BindingRestrictions restrictions, out List<Expr> sideEffects, out Expr failExpr)
        {
            var parameters = methodInfo.GetParameters();
            var isFromLua = methodInfo.Name.StartsWith(Constant.FUNCTION_PREFIX);
            var arguments = args.Select(arg => new Argument(arg.Expression, arg.LimitType)).ToList();

            // Remove closure
            if (parameters.Length > 0 && parameters[0].ParameterType == typeof(Closure))
            {
                var tempParameters = new ParameterInfo[parameters.Length - 1];
                Array.Copy(parameters, 1, tempParameters, 0, tempParameters.Length);
                parameters = tempParameters;
            }

            ExpandLastArg(arguments, args, ref restrictions);
            DefaultParamValues(arguments, parameters);
            OverflowIntoParams(arguments, parameters);
            TrimArguments(arguments, parameters, out sideEffects);
            if (isFromLua)
                DefaultParamTypeValues(arguments, parameters);
            ConvertArgumentToParamType(arguments, parameters, out failExpr);
            if (failExpr == null && !isFromLua)
                CheckNumberOfArguments(arguments, parameters, out failExpr);

            return arguments.Select(arg => arg.Expression);
        }
示例#14
0
            public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
            {
                MethodInfo method = _proxy._instanceType.GetMethod(binder.Name, args.Select(d => d.RuntimeType ?? d.LimitType.MakeByRefType()).ToArray());
                if (method == null)
                    return null;

                return new DynamicMetaObject(new DynamicMethod(method, _proxy._instance).GetMethodExpression(args.Select(arg => arg.Expression)), BindingRestrictions.GetTypeRestriction(Expression, LimitType));
            }
示例#15
0
 public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)
 {
     var args2 = args.Select(x => x.Expression).ToArray();
     var code = MakeExpression(false, Lambda.Members, args2);
     var restrictions = BindingRestrictions.GetInstanceRestriction(Expression, Value);
     return new DynamicMetaObject(code, restrictions);
 }
            public override DynamicMetaObject BindInvokeMember(
                InvokeMemberBinder binder, DynamicMetaObject[] args)
            {
                FunctionMapping mapping;
                if (FunctionMapping.SupportedFunctions.TryGetValue(new ExpressionFunction.FunctionCall(binder.Name, args.Count()), out mapping))
                {
                    var expression = Expression.New(CtorWithExpressionAndExpressionFunction,
                        new[]
                        {
                            Expression.Constant(this.Value), 
                            Expression.Constant(new ExpressionFunction(binder.Name, args.Select(x => x.Value)))
                        });

                    return new DynamicMetaObject(
                        expression,
                        BindingRestrictions.GetTypeRestriction(Expression, LimitType));
                }
                else
                {
                    return base.BindInvokeMember(binder, args);
                }
            }
示例#17
0
        public sealed override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder, DynamicMetaObject[] args)
        {
            var fallback = ((Func<Expression>)(() =>
            {
                try { return base.BindCreateInstance(binder, args).Expression; }
                catch (Exception ex) { return Expression.Throw(Expression.Constant(ex)); }
            }))();

            var dispatchResult = Expression.Parameter(typeof(DispatchResult), "dispatchResult");
            var shim = Expression.Block(dispatchResult.MkArray(),
                // 1. var dispatchResult = DispatchCreateInstance(binder, `expression`, args);
                Expression.Assign(dispatchResult, Expression.Call(
                    Expression.Constant(this),
                    typeof(SimpleMetaObject).GetMethod("DispatchCreateInstance", BF.PrivateInstance),
                    Expression.Constant(binder),
                    Expression,
                    Expression.NewArrayInit(typeof(Object), args.Select(arg => Expression.Convert(arg.Expression, typeof(Object)))))),
                // 2. return dispatchResult.Success ? dispatchResult.Result : `fallback`;
                Expression.Condition(
                    Expression.Property(dispatchResult, "Success"),
                    Expression.Convert(Expression.Property(dispatchResult, "Result"), binder.ReturnType),
                    fallback,
                    binder.ReturnType));
            return new DynamicMetaObject(shim, BindingRestrictions.GetTypeRestriction(Expression, LimitType));
        }
示例#18
0
        public sealed override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, DynamicMetaObject[] indexes)
        {
            var fallback = ((Func<Expression>)(() =>
            {
                try { return base.BindDeleteIndex(binder, indexes).Expression; }
                catch (Exception ex) { return Expression.Throw(Expression.Constant(ex)); }
            }))();

            var dispatchResult = Expression.Parameter(typeof(DispatchResult), "dispatchResult");
            var shim = Expression.Block(dispatchResult.MkArray(),
                // 1. var dispatchResult = DispatchDeleteIndex(binder, `expression`, indexes);
                Expression.Assign(dispatchResult, Expression.Call(
                    Expression.Constant(this),
                    typeof(SimpleMetaObject).GetMethod("DispatchDeleteIndex", BF.PrivateInstance),
                    Expression.Constant(binder),
                    Expression,
                    Expression.NewArrayInit(typeof(Object), indexes.Select(index => Expression.Convert(index.Expression, typeof(Object)))))),
                // 2. if (!dispatchResult.Success) `fallback`;
                Expression.IfThen(
                    Expression.Not(Expression.Property(dispatchResult, "Success")),
                    fallback));
            return new DynamicMetaObject(shim, BindingRestrictions.GetTypeRestriction(Expression, LimitType));
        }
            public override DynamicMetaObject BindInvokeMember(
                InvokeMemberBinder binder, DynamicMetaObject[] args)
            {
                if (FunctionMapping.ContainsFunction(binder.Name, args.Count()))
                {
                    var expression = Expression.New(CtorWithExpressionAndExpressionFunction,
                        new[]
                        {
                            Expression.Constant(this.Value), 
                            Expression.Constant(new ExpressionFunction(binder.Name, args.Select(x => x.Value)))
                        });

                    return new DynamicMetaObject(
                        expression,
                        BindingRestrictions.GetTypeRestriction(Expression, LimitType));
                }
                else if (string.Equals(binder.Name, ODataLiteral.Any, StringComparison.OrdinalIgnoreCase) ||
                         string.Equals(binder.Name, ODataLiteral.All, StringComparison.OrdinalIgnoreCase))
                {
                    var expression = Expression.New(CtorWithExpressionAndExpressionFunction,
                        new[]
                        {
                            Expression.Constant(this.Value), 
                            Expression.Constant(new ExpressionFunction(binder.Name, args.Select(x => x.Value)))
                        });

                    return new DynamicMetaObject(
                        expression,
                        BindingRestrictions.GetTypeRestriction(Expression, LimitType));
                }
                else if (string.Equals(binder.Name, ODataLiteral.IsOf, StringComparison.OrdinalIgnoreCase) ||
                         string.Equals(binder.Name, ODataLiteral.Is, StringComparison.OrdinalIgnoreCase) ||
                         string.Equals(binder.Name, ODataLiteral.Cast, StringComparison.OrdinalIgnoreCase) ||
                         string.Equals(binder.Name, ODataLiteral.As, StringComparison.OrdinalIgnoreCase))
                {
                    var functionName = string.Equals(binder.Name, ODataLiteral.Is, StringComparison.OrdinalIgnoreCase)
                        ? ODataLiteral.IsOf
                        : string.Equals(binder.Name, ODataLiteral.As, StringComparison.OrdinalIgnoreCase)
                            ? ODataLiteral.Cast
                            : binder.Name;
                    var expression = Expression.New(CtorWithExpressionAndExpressionFunction,
                        new[]
                        {
                            Expression.Constant(this.Value), 
                            Expression.Constant(new ExpressionFunction(
                                functionName, 
                                new [] { (this.Value as ODataExpression).IsNull ? null : this.Value, args.First().Value }))
                        });

                    return new DynamicMetaObject(
                        expression,
                        BindingRestrictions.GetTypeRestriction(Expression, LimitType));
                }
                else
                {
                    return base.BindInvokeMember(binder, args);
                }
            }
        /// <summary>
        /// Performs the binding of the dynamic operation.
        /// </summary>
        /// <param name="target">The target of the dynamic operation.</param>
        /// <param name="args">An array of arguments of the dynamic operation.</param>
        /// <returns>The System.Dynamic.DynamicMetaObject representing the result of the binding.</returns>
        public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
        {
            // Look-up the method implementation for the given selector
            // and generate an expression (runtime code) for that method.
            // This also returns the restriction needed for the PIC.
            BindingRestrictions restrictions;
            SmalltalkClass receiverClass;
            Expression expression;
            MethodLookupHelper.GetMethodInformation(this.Runtime,
                this.Selector,
                this.GetSuperLookupScope(),
                target.Value,
                target,
                args,
                out receiverClass,
                out restrictions,
                out expression);

            // If no code was generated, method is missing, and we must do #doesNotUnderstand. See DoesNotUnderstandCallSiteBinder.
            if (expression == null)
            {
                DoesNotUnderstandCallSiteBinder binder = CallSiteBinderCache.GetCache(this.Runtime).CachedDoesNotUnderstandCallSiteBinder;
                if (binder == null)
                {
                    binder = new DoesNotUnderstandCallSiteBinder(this.Runtime);
                    CallSiteBinderCache.GetCache(this.Runtime).CachedDoesNotUnderstandCallSiteBinder = binder;
                }
                expression = Expression.Dynamic(binder, typeof(Object),
                    target.Expression,
                    Expression.Constant(this.Selector, typeof(object)),
                    Expression.NewArrayInit(typeof(object), args.Select(d => Expression.Convert(d.Expression, typeof(object))).ToArray()));
            }

            // Return a DynamicMetaObject with the generated code.
            // Important here are the restrictions, which ensure that as long as <self> is
            // of the correct type, we can freely execute the code for the method we've just found.
            return new DynamicMetaObject(expression, target.Restrictions.Merge(restrictions));
        }
示例#21
0
 public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
 {
     return new DynamicMetaObject(Index.GetSetIndexedItemExpression(indexes.Select(i => i.Expression), value.Expression), BindingRestrictions.GetTypeRestriction(Expression, LimitType));
 }
示例#22
0
        public override DynamicMetaObject FallbackGetIndex(
            DynamicMetaObject target,
            DynamicMetaObject[] indexes,
            DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue) return Defer(target);

            if (target.Value == null)
            {
                return errorSuggestion ??
                       RuntimeHelper.CreateThrow(
                           target,
                           null,
                           BindingRestrictions.GetExpressionRestriction(
                               Expression.Equal(
                                   target.Expression,
                                   Expression.Constant(null, typeof (object)))),
                           typeof (InvalidOperationException),
                           "Attempted to get member from a null value.");
            }

            if (NumericHelper.IsNumeric(target.LimitType)
                || target.LimitType == typeof (string)
                || target.LimitType == typeof (UserData)
                || target.LimitType == typeof (Thread))
            {
                var h = Expression.Parameter(typeof (object));

                var args = new List<Expression> {h};

                args.AddRange(indexes.Select(i => i.Expression));

                var cond = Expression.Condition(
                    RuntimeHelper.EmitGetBinHandler(
                        _metaTables,
                        target.Expression,
                        Expression.Constant(null, typeof (object)),
                        "__index",
                        h),
                    Expression.Condition(
                        TypeHelper.EmitIsCallable(h),
                        RValueList.EmitNarrow(
                            Expression.Dynamic(
                                InvokeBinder.New(_metaTables, new CallInfo(2)),
                                typeof (object),
                                h,
                                target.Expression)),
                        Expression.Dynamic(
                            New(_metaTables, new CallInfo(1)),
                            typeof (object),
                            args.ToArray())),
                    RuntimeHelper.EmitError());

                var block = Expression.Block(
                    typeof (object),
                    new[]
                    {
                        h
                    },
                    cond);

                return new DynamicMetaObject(
                    block,
                    BindingRestrictions.GetTypeRestriction(
                        target.Expression,
                        target.LimitType));
            }

            // Find our own binding.
            const BindingFlags flags = BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public;

            if (target.Value == null)
            {
                return errorSuggestion ??
                       RuntimeHelper.CreateThrow(
                           target,
                           null,
                           BindingRestrictions.GetExpressionRestriction(
                               Expression.Equal(
                                   target.Expression,
                                   Expression.Constant(null, typeof (object)))),
                           typeof (InvalidOperationException),
                           "Attempted to get member from a null value.");
            }

            var members = target.LimitType.GetMember("get_Item", flags);

            if (members.Length == 1)
            {
                // Don't need restriction test for name since this
                // rule is only used where binder is used, which is
                // only used in sites with this binder.Name.
                return new DynamicMetaObject(
                    Expression.MakeMemberAccess(
                        Expression.Convert(target.Expression, members[0].DeclaringType),
                        members[0]),
                    RuntimeHelper.MatchTypeOrNull(target, target.LimitType));
            }

            return errorSuggestion ??
                   RuntimeHelper.CreateThrow(
                       target,
                       null,
                       RuntimeHelper.MatchTypeOrNull(target, target.LimitType),
                       typeof (MissingMemberException),
                       "cannot bind member, get_Item, on object" + target.Value);
        }
            public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
            {
                Expression self = Expression.Convert(Expression, LimitType);

                Expression[] parameters = new Expression[2];
                parameters[0] = Expression.Constant(binder.Name);
                parameters[1] = Expression.NewArrayInit(typeof(object), args.Select(dmo => dmo.Expression).ToArray());

                return new DynamicMetaObject(
                    Expression.Call(self, typeof(AutofacRegistrationHelper).GetMethod("InvokeMember", BindingFlags.NonPublic | BindingFlags.Instance), parameters),
                    BindingRestrictions.GetTypeRestriction(Expression, LimitType));
            }