} // func InvokeExpression private static Expression InvokeMemberExpression(Scope scope, Token tStart, Expression instance, string memberName, InvokeResult result, ArgumentsList arguments) { if (LuaEmit.IsDynamicType(instance.Type) || arguments.Expressions.Any(c => LuaEmit.IsDynamicType(c.Type))) { var dynamicArguments = new Expression[arguments.Count + 1]; // first argument is the instance dynamicArguments[0] = ConvertObjectExpression(scope.Runtime, tStart, instance, false); if (arguments.Count > 0) { // single object for (var i = 0; i < arguments.Count - 1; i++) { dynamicArguments[i + 1] = ConvertObjectExpression(scope.Runtime, tStart, arguments.Expressions[i], false); } // last argument is different if (arguments.CallInfo.ArgumentNames.Count > 0) { dynamicArguments[dynamicArguments.Length - 1] = ConvertObjectExpression(scope.Runtime, tStart, arguments.Expressions[arguments.Count - 1], false); } else { dynamicArguments[dynamicArguments.Length - 1] = Lua.EnsureType(arguments.Expressions[arguments.Count - 1], typeof(object)); } } return(EnsureInvokeResult(scope, tStart, DynamicExpression.Dynamic(scope.Runtime.GetInvokeMemberBinder(memberName, arguments.CallInfo), typeof(object), dynamicArguments), result, instance, memberName )); } else { return(EnsureInvokeResult(scope, tStart, SafeExpression(() => { Expression expr; if (!LuaEmit.TryInvokeMember <Expression>(scope.Runtime, LuaType.GetType(instance.Type), instance, arguments.CallInfo, arguments.Expressions, memberName, false, e => e, e => e.Type, true, out expr)) { throw new LuaEmitException(LuaEmitException.MemberNotFound, instance.Type, memberName); } return expr; }, tStart), result, instance, memberName )); } } // func InvokeMemberExpression
} // func FallbackInvoke public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion) { // defer target and all arguments if (!target.HasValue || args.Any(c => !c.HasValue)) { return(Defer(target, args)); } if (target.Value == null) { return(errorSuggestion ?? new DynamicMetaObject( ThrowExpression(Resources.rsNilNotCallable, ReturnType), target.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, null)) )); } else { try { var luaType = LuaType.GetType(target.LimitType); Expression expr; if (LuaEmit.TryInvokeMember <DynamicMetaObject>(lua, luaType, target, CallInfo, args, Name, IgnoreCase, mo => mo.Expression, mo => mo.LimitType, false, out expr)) { return(new DynamicMetaObject(Lua.EnsureType(expr, ReturnType), GetMethodSignatureRestriction(target, args))); } else { return(errorSuggestion ?? new DynamicMetaObject (ThrowExpression(String.Format(Resources.rsMemberNotResolved, luaType.FullName, Name), ReturnType), GetMethodSignatureRestriction(target, args) )); } } catch (LuaEmitException e) { return(errorSuggestion ?? new DynamicMetaObject(ThrowExpression(e.Message, ReturnType), GetMethodSignatureRestriction(target, args))); } } } // func FallbackInvokeMember