Exemple #1
0
        private ParameterWrapper CreateParameterWrapper(ParameterInfo info)
        {
            bool isParamArray       = Overload.IsParamArray(info.Position);
            bool isParamDict        = !isParamArray && Overload.IsParamDictionary(info.Position);
            bool prohibitsNullItems = (isParamArray || isParamDict) && Overload.ProhibitsNullItems(info.Position);

            return(new ParameterWrapper(
                       info,
                       info.ParameterType,
                       info.Name,
                       (Overload.ProhibitsNull(info.Position) ? ParameterBindingFlags.ProhibitNull : 0) |
                       (prohibitsNullItems ? ParameterBindingFlags.ProhibitNullItems : 0) |
                       (isParamArray ? ParameterBindingFlags.IsParamArray : 0) |
                       (isParamDict ? ParameterBindingFlags.IsParamDictionary : 0)
                       ));
        }
Exemple #2
0
        /// <summary>
        /// Builds a new MethodCandidate which takes count arguments and the provided list of keyword arguments.
        ///
        /// The basic idea here is to figure out which parameters map to params or a dictionary params and
        /// fill in those spots w/ extra ParameterWrapper's.
        /// </summary>
        internal MethodCandidate MakeParamsExtended(int count, IList <string> names)
        {
            Debug.Assert(Overload.IsVariadic);

            List <ParameterWrapper> newParameters = new List <ParameterWrapper>(count);

            // keep track of which named args map to a real argument, and which ones
            // map to the params dictionary.
            List <string> unusedNames       = new List <string>(names);
            List <int>    unusedNameIndexes = new List <int>();

            for (int i = 0; i < unusedNames.Count; i++)
            {
                unusedNameIndexes.Add(i);
            }

            // if we don't have a param array we'll have a param dict which is type object
            ParameterWrapper paramsArrayParameter = null;
            int paramsArrayIndex = -1;

            for (int i = 0; i < _parameters.Count; i++)
            {
                ParameterWrapper parameter = _parameters[i];

                if (parameter.IsParamsArray)
                {
                    paramsArrayParameter = parameter;
                    paramsArrayIndex     = i;
                }
                else
                {
                    int j = unusedNames.IndexOf(parameter.Name);
                    if (j != -1)
                    {
                        unusedNames.RemoveAt(j);
                        unusedNameIndexes.RemoveAt(j);
                    }
                    newParameters.Add(parameter);
                }
            }

            if (paramsArrayIndex != -1)
            {
                ParameterWrapper expanded = paramsArrayParameter.Expand();
                while (newParameters.Count < (count - unusedNames.Count))
                {
                    newParameters.Insert(System.Math.Min(paramsArrayIndex, newParameters.Count), expanded);
                }
            }

            if (_paramsDict != null)
            {
                var flags = (Overload.ProhibitsNullItems(_paramsDict.ParameterInfo.Position) ? ParameterBindingFlags.ProhibitNull : 0) |
                            (_paramsDict.IsHidden ? ParameterBindingFlags.IsHidden : 0);

                foreach (string name in unusedNames)
                {
                    newParameters.Add(new ParameterWrapper(_paramsDict.ParameterInfo, typeof(object), name, flags));
                }
            }
            else if (unusedNames.Count != 0)
            {
                // unbound kw args and no where to put them, can't call...
                // TODO: We could do better here because this results in an incorrect arg # error message.
                return(null);
            }

            // if we have too many or too few args we also can't call
            if (count != newParameters.Count)
            {
                return(null);
            }

            return(MakeParamsExtended(unusedNames.ToArray(), unusedNameIndexes.ToArray(), newParameters));
        }