Microsoft.CSharp.RuntimeBinder.RuntimeBinder.CreateArgumentArray C# (CSharp) Method

CreateArgumentArray() private method

private CreateArgumentArray ( DynamicMetaObjectBinder payload, IEnumerable parameters, DynamicMetaObject args ) : ArgumentObject[]
payload System.Dynamic.DynamicMetaObjectBinder
parameters IEnumerable
args System.Dynamic.DynamicMetaObject
return ArgumentObject[]
        private ArgumentObject[] CreateArgumentArray(
                DynamicMetaObjectBinder payload,
                IEnumerable<Expression> parameters,
                DynamicMetaObject[] args)
        {
            // Check the payloads to see whether or not we need to get the runtime types for
            // these arguments.

            List<ArgumentObject> list = new List<ArgumentObject>();
            Func<DynamicMetaObjectBinder, CSharpArgumentInfo, Expression, DynamicMetaObject, int, Type> getArgumentType = null;
            Func<DynamicMetaObjectBinder, int, CSharpArgumentInfo> getArgumentInfo = null;

            // Quick delegate to set the type.
            if (payload is ICSharpInvokeOrInvokeMemberBinder)
            {
                getArgumentInfo = (p, index) => (p as ICSharpInvokeOrInvokeMemberBinder).ArgumentInfo[index];
            }
            else if (payload is CSharpBinaryOperationBinder)
            {
                getArgumentInfo = (p, index) => (p as CSharpBinaryOperationBinder).ArgumentInfo[index];
            }
            else if (payload is CSharpUnaryOperationBinder)
            {
                getArgumentInfo = (p, index) => (p as CSharpUnaryOperationBinder).ArgumentInfo[index];
            }
            else if (payload is CSharpGetMemberBinder)
            {
                getArgumentInfo = (p, index) => (p as CSharpGetMemberBinder).ArgumentInfo[index];
            }
            else if (payload is CSharpSetMemberBinder)
            {
                getArgumentInfo = (p, index) => (p as CSharpSetMemberBinder).ArgumentInfo[index];
            }
            else if (payload is CSharpGetIndexBinder)
            {
                getArgumentInfo = (p, index) => (p as CSharpGetIndexBinder).ArgumentInfo[index];
            }
            else if (payload is CSharpSetIndexBinder)
            {
                getArgumentInfo = (p, index) => (p as CSharpSetIndexBinder).ArgumentInfo[index];
            }
            else if (payload is CSharpConvertBinder || payload is CSharpIsEventBinder)
            {
                getArgumentInfo = (p, index) => CSharpArgumentInfo.None;
            }
            else
            {
                Debug.Assert(false, "Unknown payload kind");
                throw Error.InternalCompilerError();
            }
            getArgumentType = (p, argInfo, param, arg, index) =>
                {
                    Type t = argInfo.UseCompileTimeType ? param.Type : arg.LimitType;
                    Debug.Assert(t != null);

                    if ((argInfo.Flags & (CSharpArgumentInfoFlags.IsRef | CSharpArgumentInfoFlags.IsOut)) != 0)
                    {
                        // If we have a ref our an out parameter, make the byref type.
                        // If we have the receiver of a call or invoke that is ref, it must be because of 
                        // a struct caller. Don't persist the ref for that.
                        if (!(index == 0 && IsBinderThatCanHaveRefReceiver(p)))
                        {
                            t = t.MakeByRefType();
                        }
                    }
                    else if (!argInfo.UseCompileTimeType)
                    {
                        // If we don't have ref or out, then pick the best type to represent this value.
                        // If the runtime value has a type that is not accessible, then we pick an
                        // accessible type that is "closest" in some sense, where we recursively widen
                        // components of type that can validly vary covariantly.

                        // This ensures that the type we pick is something that the user could have written.

                        CType actualType = _symbolTable.GetCTypeFromType(t);
                        CType bestType;

                        bool res = _semanticChecker.GetTypeManager().GetBestAccessibleType(_semanticChecker, _bindingContext, actualType, out bestType);
                        
                        // Since the actual type of these arguments are never going to be pointer
                        // types or ref/out types (they are in fact boxed into an object), we have
                        // a guarantee that we will always be able to find a best accessible type
                        // (which, in the worst case, may be object).
                        Debug.Assert(res, "Unexpected failure of GetBestAccessibleType in construction of argument array");

                        t = bestType.AssociatedSystemType;
                    }

                    return t;
                };

            int i = 0;
            foreach (var curParam in parameters)
            {
                ArgumentObject a = new ArgumentObject();
                a.Value = args[i].Value;
                a.Info = getArgumentInfo(payload, i);
                a.Type = getArgumentType(payload, a.Info, curParam, args[i], i);

                Debug.Assert(a.Type != null);
                list.Add(a);

                ++i;
            }

            return list.ToArray();
        }