} // ctor public override DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion) { // defer target and all arguments if (!target.HasValue || !arg.HasValue) { return(Defer(target, arg)); } Expression expr; try { expr = EnsureType(LuaEmit.BinaryOperationExpression(lua, lInteger && Operation == ExpressionType.Divide ? Lua.IntegerDivide : Operation, target.Expression, target.LimitType, arg.Expression, arg.LimitType, false), this.ReturnType); } catch (LuaEmitException e) { if (errorSuggestion != null) { return(errorSuggestion); } expr = ThrowExpression(e.Message, this.ReturnType); } // restrictions var restrictions = target.Restrictions .Merge(arg.Restrictions) .Merge(Lua.GetSimpleRestriction(target)) .Merge(Lua.GetSimpleRestriction(arg)); return(new DynamicMetaObject(expr, restrictions)); } // func FallbackBinaryOperation
} // ctor public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion) { // defer the target if (!target.HasValue) { return(Defer(target)); } if (target.Value == null) { return(errorSuggestion ?? new DynamicMetaObject( ThrowExpression(String.Format(Properties.Resources.rsMemberNotResolved, target.LimitType.Name, Name), ReturnType), target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, null)) )); } else { Expression expr; try { expr = Lua.EnsureType(LuaEmit.SetMember(lua, target.Expression, target.LimitType, Name, IgnoreCase, value.Expression, value.LimitType, false), ReturnType); } catch (LuaEmitException e) { if (errorSuggestion != null) { return(errorSuggestion); } expr = ThrowExpression(e.Message, ReturnType); } return(new DynamicMetaObject( expr, target.Restrictions.Merge(BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType).Merge(Lua.GetSimpleRestriction(value))) )); } } // func FallbackSetMember
} // ctor public override DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion) { // Defer the parameters if (!target.HasValue || indexes.Any(c => !c.HasValue)) { DynamicMetaObject[] def = new DynamicMetaObject[indexes.Length + 1]; def[0] = target; Array.Copy(indexes, 0, def, 1, indexes.Length); return(Defer(def)); } Expression expr; if (target.Value == null) { if (errorSuggestion != null) { return(errorSuggestion); } expr = ThrowExpression(Properties.Resources.rsNullReference, ReturnType); } else { try { expr = Lua.EnsureType(LuaEmit.SetIndex(lua, target, indexes, value, mo => mo.Expression, mo => mo.LimitType, false), ReturnType); } catch (LuaEmitException e) { if (errorSuggestion != null) { return(errorSuggestion); } expr = ThrowExpression(e.Message, ReturnType); } } return(new DynamicMetaObject(expr, GetMethodSignatureRestriction(target, indexes).Merge(Lua.GetSimpleRestriction(value)))); } // func FallbackSetIndex
} // ctor public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion) { // defer the target if (!target.HasValue) { return(Defer(target)); } if (target.Value == null) { return(errorSuggestion ?? new DynamicMetaObject( ThrowExpression(String.Format(Resources.rsMemberNotResolved, target.LimitType.Name, Name), ReturnType), target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, null)) )); } else { Expression expr; // restrictions var restrictions = target.Restrictions.Merge(BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType)); // try to bind the member switch (LuaEmit.TrySetMember(target.Expression, target.LimitType, Name, IgnoreCase, (setType) => LuaEmit.ConvertWithRuntime(Lua, value.Expression, value.LimitType, setType), out expr)) { case LuaTrySetMemberReturn.None: return(errorSuggestion ?? new DynamicMetaObject(ThrowExpression(LuaEmitException.GetMessageText(LuaEmitException.MemberNotFound, target.LimitType.Name, Name), ReturnType), restrictions)); case LuaTrySetMemberReturn.NotWritable: return(errorSuggestion ?? new DynamicMetaObject(ThrowExpression(LuaEmitException.GetMessageText(LuaEmitException.CanNotWriteMember, target.LimitType.Name, Name), ReturnType), restrictions)); case LuaTrySetMemberReturn.ValidExpression: return(new DynamicMetaObject(Lua.EnsureType(expr, ReturnType), restrictions.Merge(Lua.GetSimpleRestriction(value)))); default: throw new ArgumentException("return of TryGetMember."); } } } // func FallbackSetMember