public void MapParameter(ParameterInfo pi) { int indexForArgBuilder; int nameIndex = _argNames.IndexOf(pi.Name); 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 refType = typeof(StrongBox<>).MakeGenericType(pi.ParameterType.GetElementType()); _parameters.Add(new ParameterWrapper(pi, refType, pi.Name, ParameterBindingFlags.ProhibitNull)); ab = new ReferenceArgBuilder(pi, refType, indexForArgBuilder); } else if (pi.Position == 0 && _overload.IsExtension) { _parameters.Add(new ParameterWrapper(pi, pi.ParameterType, pi.Name, ParameterBindingFlags.IsHidden)); ab = new SimpleArgBuilder(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)); } }