Exemple #1
0
        public void MapParameter(ParameterInfo pi)
        {
            int indexForArgBuilder;
            int nameIndex = _resolver.AllowByKeywordArgument(Overload, pi) ? _argNames.IndexOf(pi.Name) : -1;

            if (nameIndex == -1)
            {
                // positional argument, we simply consume the next argument
                indexForArgBuilder = ArgIndex++;
            }
            else
            {
                // keyword argument, we just tell the simple arg builder to consume arg 0.
                // KeywordArgBuilder will then pass in the correct single argument based
                // upon the actual argument number provided by the user.
                indexForArgBuilder = 0;
            }

            // if the parameter is default we need to build a default arg builder and then
            // build a reduced method at the end.
            if (!pi.IsMandatory())
            {
                // We need to build the default builder even if we have a parameter for it already to
                // get good consistency of our error messages.  But consider a method like
                // def foo(a=1, b=2) and the user calls it as foo(b=3). Then adding the default
                // value breaks an otherwise valid call.  This is because we only generate MethodCandidates
                // filling in the defaults from right to left (so the method - 1 arg requires a,
                // and the method minus 2 args requires b).  So we only add the default if it's
                // a positional arg or we don't already have a default value.
                if (nameIndex == -1 || !_hasDefaults)
                {
                    _defaultArguments.Add(new DefaultArgBuilder(pi));
                    _hasDefaults = true;
                }
                else
                {
                    _defaultArguments.Add(null);
                }
            }
            else if (_defaultArguments.Count > 0)
            {
                // non-contigious default parameter
                _defaultArguments.Add(null);
            }

            ArgBuilder ab;

            if (pi.ParameterType.IsByRef)
            {
                _hasByRef = true;
                Type elementType = pi.ParameterType.GetElementType();
                Type refType     = typeof(StrongBox <>).MakeGenericType(elementType);
                _parameters.Add(new ParameterWrapper(pi, refType, pi.Name, ParameterBindingFlags.ProhibitNull));
                ab = new ReferenceArgBuilder(pi, elementType, refType, indexForArgBuilder);
            }
            else if (pi.Position == 0 && Overload.IsExtension)
            {
                _parameters.Add(new ParameterWrapper(pi, pi.ParameterType, pi.Name, ParameterBindingFlags.IsHidden));
                ab = new SimpleArgBuilder(pi, pi.ParameterType, indexForArgBuilder, false, false);
            }
            else
            {
                ab = AddSimpleParameterMapping(pi, indexForArgBuilder);
            }

            if (nameIndex == -1)
            {
                _arguments.Add(ab);
            }
            else
            {
                Debug.Assert(KeywordArgBuilder.BuilderExpectsSingleParameter(ab));
                _arguments.Add(new KeywordArgBuilder(ab, _argNames.Count, nameIndex));
            }
        }