private static Expression MemberSetExpressionCore(Lua lua, Token tokenStart, Expression instance, string memberName, Expression set) { if (LuaEmit.IsDynamicType(instance.Type)) // first call the dynamic interface { return(DynamicExpression.Dynamic(lua.GetSetMemberBinder(memberName), typeof(object), ConvertObjectExpression(lua, tokenStart, instance, true), ConvertObjectExpression(lua, tokenStart, set, true) )); } else { Expression result; switch (LuaEmit.TrySetMember(instance, instance.Type, memberName, false, (setType) => ConvertExpression(lua, tokenStart, set, setType), out result)) { case LuaTrySetMemberReturn.None: throw ParseError(tokenStart, LuaEmitException.GetMessageText(LuaEmitException.MemberNotFound, instance.Type.Name, memberName)); case LuaTrySetMemberReturn.NotWritable: throw ParseError(tokenStart, LuaEmitException.GetMessageText(LuaEmitException.CanNotWriteMember, instance.Type.Name, memberName)); case LuaTrySetMemberReturn.ValidExpression: return(result); default: throw new ArgumentException("Internal return type of TrySetMember"); } } } // func MemberSetExpressionCore
} // 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