public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args) { MethodInfo method = typeof(IApply).GetMethod("Apply"); var list = new List <Expression>(); foreach (var arg in args) { list.Add(Runtime.ConvertArgument(arg, typeof(object))); } var callArg = Expression.NewArrayInit(typeof(object), list); var expr = Expression.Call(Expression.Convert(Expression, typeof(T)), method, callArg); var restrictions = BindingRestrictions.GetTypeRestriction(Expression, typeof(T)); return(new DynamicMetaObject(Runtime.EnsureObjectResult(expr), restrictions)); }
public override DynamicMetaObject FallbackSetIndex( DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion) { var deferArgs = Runtime.CheckDeferArgs(target, indexes); if (deferArgs != null) { return(Defer(deferArgs)); } if (target.Value == null) { return(Runtime.CheckTargetNullReference(target, "Cannot set index on null reference: " + target.LimitType.FullName + Runtime.CollectParameterInfo(target, indexes))); } Debug.Assert(target.HasValue && target.LimitType != typeof(Array)); Type valueType; var indexingExpr = Runtime.GetIndexingExpression(target, indexes, out valueType); if (indexingExpr == null) { return(errorSuggestion ?? Runtime.CreateThrow( target, indexes, BindingRestrictions.Empty, typeof(InvalidOperationException), "No set indexer found: " + target.LimitType.FullName + Runtime.CollectParameterInfo(target, indexes))); } var setIndexExpr = Expression.Assign(indexingExpr, Runtime.ConvertArgument(value, valueType)); BindingRestrictions restrictions = Runtime.GetTargetArgsRestrictions(target, indexes, false); return(new DynamicMetaObject(Runtime.EnsureObjectResult(setIndexExpr), restrictions)); }
public override DynamicMetaObject FallbackSetMember( DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion) { // Used by (set-attr obj name value) if (!target.HasValue) { return(Defer(target)); } var name = Name.LispToPascalCaseName(); if (target.Value == null) { var id = target.LimitType.Name + "." + name; return(Runtime.CheckTargetNullReference(target, "Cannot set property on null reference:" + id + "(null)")); } var flags = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy; var members = target.LimitType.GetMember(name, flags); if (members.Length == 1 && members[0] is PropertyInfo) { var prop = (PropertyInfo)members[0]; var val = Runtime.ConvertArgument(value, prop.PropertyType); var expr = Expression.Assign(Expression.MakeMemberAccess(Expression.Convert(target.Expression, prop.DeclaringType), prop), val); return(new DynamicMetaObject(Runtime.EnsureObjectResult(expr), BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType))); } else if (members.Length == 1 && members[0] is FieldInfo) { var field = (FieldInfo)members[0]; var val = Runtime.ConvertArgument(value, field.FieldType); var expr = Expression.Assign(Expression.MakeMemberAccess(Expression.Convert(target.Expression, field.DeclaringType), field), val); return(new DynamicMetaObject(Runtime.EnsureObjectResult(expr), BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType))); } else if (members.Length == 1 && members[0] is EventInfo) { //public static void AddEventHandler( System.Reflection.EventInfo eventinfo, object target, object func ) var evt = (EventInfo)members[0]; var expr = Expression.Call(Runtime.AddEventHandlerMethod, Expression.Constant(evt, typeof(EventInfo)), Expression.Convert(target.Expression, evt.DeclaringType), Expression.Convert(value.Expression, typeof(IApply))); return(new DynamicMetaObject(Runtime.EnsureObjectResult(expr), BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType))); } else { return(errorSuggestion ?? Runtime.CreateThrow( target, null, BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType), typeof(MissingMemberException), "Property or field not found: " + target.LimitType.Name + "." + name + Runtime.CollectParameterInfo(target))); } }