private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) { DynamicMetaObject obj2 = fallback(null); ParameterExpression left = Expression.Parameter(typeof(object), null); Expression[] arguments = args.AddFirst<Expression>(Constant(binder)); arguments[args.Length] = Expression.Assign(left, arguments[args.Length]); DynamicMetaObject errorSuggestion = new DynamicMetaObject(Expression.Block(new ParameterExpression[] { left }, new Expression[] { Expression.Condition(Expression.Call(this.GetLimitedSelf(), typeof(DynamicObject).GetMethod(methodName), arguments), left, obj2.Expression, typeof(object)) }), this.GetRestrictions().Merge(obj2.Restrictions)); return fallback(errorSuggestion); }
/// <summary> /// Helper method for generating a MetaObject which calls a /// specific method on Dynamic, but uses one of the arguments for /// the result. /// </summary> private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) { // // First, call fallback to do default binding // This produces either an error or a call to a .NET member // DynamicMetaObject fallbackResult = fallback(null); // // Build a new expression like: // TryDeleteMember(payload) ? null : fallbackResult // var callDynamic = new DynamicMetaObject( Expression.Condition( Expression.Call( GetLimitedSelf(), typeof(DynamicObject).GetMethod(methodName), args.AddFirst(Constant(binder)) ), Expression.Constant(null), DynamicMetaObjectBinder.Convert(fallbackResult.Expression, typeof(object)) ), GetRestrictions().Merge(fallbackResult.Restrictions) ); // // Now, call fallback again using our new MO as the error // When we do this, one of two things can happen: // 1. Binding will succeed, and it will ignore our call to // the dynamic method, OR // 2. Binding will fail, and it will use the MO we created // above. // return fallback(callDynamic); }
private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) { DynamicMetaObject obj2 = fallback(null); DynamicMetaObject errorSuggestion = new DynamicMetaObject(Expression.Condition(Expression.Call(this.GetLimitedSelf(), typeof(DynamicObject).GetMethod(methodName), args.AddFirst<Expression>(Constant(binder))), Expression.Empty(), obj2.Expression, typeof(void)), this.GetRestrictions().Merge(obj2.Restrictions)); return fallback(errorSuggestion); }
/// <summary> /// Helper method for generating a MetaObject which calls a /// specific method on Dynamic, but uses one of the arguments for /// the result. /// </summary> private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) { // // First, call fallback to do default binding // This produces either an error or a call to a .NET member // DynamicMetaObject fallbackResult = fallback(null); // // Build a new expression like: // { // object result; // TrySetMember(payload, result = value) ? result : fallbackResult // } // var result = Expression.Parameter(typeof(object), null); var callArgs = args.AddFirst(Constant(binder)); callArgs[args.Length] = Expression.Assign(result, callArgs[args.Length]); var callDynamic = new DynamicMetaObject( Expression.Block( new[] { result }, Expression.Condition( Expression.Call( GetLimitedSelf(), typeof(DynamicObject).GetMethod(methodName), callArgs ), result, DynamicMetaObjectBinder.Convert(fallbackResult.Expression, typeof(object)) ) ), GetRestrictions().Merge(fallbackResult.Restrictions) ); // // Now, call fallback again using our new MO as the error // When we do this, one of two things can happen: // 1. Binding will succeed, and it will ignore our call to // the dynamic method, OR // 2. Binding will fail, and it will use the MO we created // above. // return fallback(callDynamic); }