Example #1
0
        /// <summary>
        /// Binds named arguments to the parameters. Returns a permutation of indices that captures the relationship between 
        /// named arguments and their corresponding parameters. Checks for duplicate and unbound named arguments.
        /// 
        /// Ensures that for all i: namedArgs[i] binds to parameters[args.Length + bindingPermutation[i]] 
        /// </summary>
        internal bool TryBindNamedArguments(MethodCandidate method, out ArgumentBinding binding, out CallFailure failure) {
            if (_namedArgs.Count == 0) {
                binding = new ArgumentBinding(_args.Count);
                failure = null;
                return true;
            }

            var permutation = new int[_namedArgs.Count];
            var boundParameters = new BitArray(_namedArgs.Count);

            for (int i = 0; i < permutation.Length; i++) {
                permutation[i] = -1;
            }

            List<string> unboundNames = null;
            List<string> duppedNames = null;

            int positionalArgCount = _args.Count;

            for (int i = 0; i < _names.Count; i++) {
                int paramIndex = method.IndexOfParameter(_names[i]);
                if (paramIndex >= 0) {
                    int nameIndex = paramIndex - positionalArgCount;

                    // argument maps to already bound parameter:
                    if (paramIndex < positionalArgCount || boundParameters[nameIndex]) {
                        if (duppedNames == null) {
                            duppedNames = new List<string>();
                        }
                        duppedNames.Add(_names[i]);
                    } else {
                        permutation[i] = nameIndex;
                        boundParameters[nameIndex] = true;
                    }
                } else {
                    if (unboundNames == null) {
                        unboundNames = new List<string>();
                    }
                    unboundNames.Add(_names[i]);
                }
            }

            binding = new ArgumentBinding(positionalArgCount, permutation);

            if (unboundNames != null) {
                failure = new CallFailure(method, unboundNames.ToArray(), true);
                return false;
            } else if (duppedNames != null) {
                failure = new CallFailure(method, duppedNames.ToArray(), false);
                return false;
            }

            failure = null;
            return true;
        }
Example #2
0
 internal ParameterWrapper GetParameter(int argumentIndex, ArgumentBinding namesBinding) {
     return _parameters[namesBinding.ArgumentToParameter(argumentIndex)];
 }
Example #3
0
 internal ParameterWrapper GetParameter(int argumentIndex, ArgumentBinding namesBinding)
 {
     return(_parameters[namesBinding.ArgumentToParameter(argumentIndex)]);
 }
Example #4
0
        private bool TryConvertArguments(MethodCandidate candidate, ArgumentBinding namesBinding, NarrowingLevel narrowingLevel, out CallFailure failure) {
            Debug.Assert(_actualArguments.Count == candidate.ParameterCount);

            BitArray hasConversion = new BitArray(_actualArguments.Count);

            bool success = true;
            for (int i = 0; i < _actualArguments.Count; i++) {
                success &= (hasConversion[i] = CanConvertFrom(_actualArguments[i].GetLimitType(), _actualArguments[i], candidate.GetParameter(i, namesBinding), narrowingLevel));
            }

            if (!success) {
                var conversionResults = new ConversionResult[_actualArguments.Count];
                for (int i = 0; i < _actualArguments.Count; i++) {
                    conversionResults[i] = new ConversionResult(_actualArguments[i].Value, _actualArguments[i].GetLimitType(), candidate.GetParameter(i, namesBinding).Type, !hasConversion[i]);
                }
                failure = new CallFailure(candidate, conversionResults);
            } else {
                failure = null;
            }

            return success;
        }
Example #5
0
 internal ApplicableCandidate(MethodCandidate method, ArgumentBinding argBinding)
 {
     Assert.NotNull(method, argBinding);
     Method          = method;
     ArgumentBinding = argBinding;
 }
Example #6
0
 internal ApplicableCandidate(MethodCandidate method, ArgumentBinding argBinding)
 {
     Assert.NotNull(method, argBinding);
     Method = method;
     ArgumentBinding = argBinding;
 }
Example #7
0
        /// <summary>
        /// Binds named arguments to the parameters. Returns a permutation of indices that captures the relationship between
        /// named arguments and their corresponding parameters. Checks for duplicate and unbound named arguments.
        /// Ensures that for all i: namedArgs[i] binds to parameters[args.Length + bindingPermutation[i]]
        /// </summary>
        internal bool TryBindNamedArguments(MethodCandidate method, out ArgumentBinding binding, out CallFailure failure)
        {
            if (NamedArguments.Count == 0)
            {
                binding = new ArgumentBinding(Arguments.Count);
                failure = null;
                return(true);
            }

            var permutation     = new int[NamedArguments.Count];
            var boundParameters = new BitArray(NamedArguments.Count);

            for (int i = 0; i < permutation.Length; i++)
            {
                permutation[i] = -1;
            }

            List <string> unboundNames      = null;
            List <string> duppedNames       = null;
            List <int>    duppedPositionals = null;

            int positionalArgCount = Arguments.Count;

            for (int i = 0; i < ArgNames.Count; i++)
            {
                int paramIndex = method.IndexOfParameter(ArgNames[i]);
                if (paramIndex >= 0)
                {
                    int nameIndex = paramIndex - positionalArgCount;

                    if (paramIndex < positionalArgCount)
                    {
                        // argument maps to already bound positional parameter
                        duppedNames ??= new List <string>();
                        duppedPositionals ??= Enumerable.Repeat(0, duppedNames.Count).ToList();
                        duppedNames.Add(ArgNames[i]);
                        duppedPositionals.Add(method.PositionOfParameter(ArgNames[i]));
                    }
                    else if (boundParameters[nameIndex])
                    {
                        // argument maps to already bound named parameter
                        duppedNames ??= new List <string>();
                        duppedNames.Add(ArgNames[i]);
                        duppedPositionals?.Add(0);
                    }
                    else
                    {
                        permutation[i]             = nameIndex;
                        boundParameters[nameIndex] = true;
                    }
                }
                else
                {
                    unboundNames ??= new List <string>();
                    unboundNames.Add(ArgNames[i]);
                }
            }

            Debug.Assert(duppedPositionals == null || (duppedNames != null && duppedNames.Count == duppedPositionals.Count));

            binding = new ArgumentBinding(positionalArgCount, permutation);

            if (unboundNames != null)
            {
                failure = new CallFailure(method, unboundNames.ToArray());
                return(false);
            }

            if (duppedNames != null)
            {
                failure = new CallFailure(method, duppedNames.ToArray(), duppedPositionals?.ToArray());
                return(false);
            }

            failure = null;
            return(true);
        }