Example #1
0
        internal static MethodCandidate InferGenericMethod(ApplicableCandidate /*!*/ candidate, ActualArguments /*!*/ actualArgs)
        {
            OverloadInfo target = candidate.Method.Overload;

            Assert.NotNull(target);
            Debug.Assert(target.IsGenericMethodDefinition);
            Debug.Assert(target.IsGenericMethod && target.ContainsGenericParameters);

            List <DynamicMetaObject /*!*/> args = GetAllArguments(candidate, actualArgs);

            if (args == null)
            {
                return(null);
            }

            Dictionary <Type, List <Type> > dependencies = GetDependencyMapping(target);

            Type[] genArgs = GetSortedGenericArguments(target, dependencies);
            Dictionary <Type, ArgumentInputs> inputs = GetArgumentToInputMapping(candidate.Method, args);

            // now process the inputs
            var  binding      = new Dictionary <Type, Type>();
            var  restrictions = new Dictionary <DynamicMetaObject, BindingRestrictions>();
            bool noMethod     = false;

            foreach (Type t in genArgs)
            {
                if (!inputs.TryGetValue(t, out ArgumentInputs inps))
                {
                    continue;
                }

                Type bestType = inps.GetBestType(candidate.Method.Resolver, binding, restrictions);
                if (bestType == null)
                {
                    // we conflict with possible constraints
                    noMethod = true;
                    break;
                }
            }

            if (!noMethod)
            {
                // finally build a new MethodCandidate for the generic method
                genArgs = GetGenericArgumentsForInferedMethod(target, binding);
                if (genArgs == null)
                {
                    // not all types we're inferred
                    return(null);
                }

                OverloadInfo newMethod = target.MakeGenericMethod(genArgs);

                List <ParameterWrapper> newWrappers = CreateNewWrappers(candidate.Method, newMethod, target);

                List <ArgBuilder> argBuilders = CreateNewArgBuilders(candidate.Method, newMethod);
                if (argBuilders == null)
                {
                    // one or more arg builders don't support type inference
                    return(null);
                }

                if (restrictions.Count == 0)
                {
                    restrictions = null;
                }

                // create the new method candidate
                return(candidate.Method.ReplaceMethod(newMethod, newWrappers, argBuilders, restrictions));
            }

            return(null);
        }
Example #2
0
        private static List <DynamicMetaObject> GetAllArguments(ApplicableCandidate candidate, ActualArguments actualArgs)
        {
            List <DynamicMetaObject> args = new List <DynamicMetaObject>();

            for (int i = 0; i < actualArgs.Count; i++)
            {
                int index = candidate.ArgumentBinding.ArgumentToParameter(i);
                if (index < actualArgs.Arguments.Count)
                {
                    args.Add(actualArgs.Arguments[index]);
                }
                else
                {
                    args.Add(actualArgs.NamedArguments[index - actualArgs.Arguments.Count]);
                }
            }
            return(args);
        }
Example #3
0
        internal static MethodCandidate InferGenericMethod(ApplicableCandidate/*!*/ candidate, ActualArguments/*!*/ actualArgs) {
            OverloadInfo target = candidate.Method.Overload;
            Assert.NotNull(target);
            Debug.Assert(target.IsGenericMethodDefinition);
            Debug.Assert(target.IsGenericMethod && target.ContainsGenericParameters);

            List<DynamicMetaObject/*!*/> args = GetAllArguments(candidate, actualArgs);
            if (args == null) {
                return null;
            }

            Dictionary<Type, List<Type>> dependencies = GetDependencyMapping(target);
            Type[] genArgs = GetSortedGenericArguments(target, dependencies);
            Dictionary<Type, ArgumentInputs> inputs = GetArgumentToInputMapping(candidate.Method, args);

            // now process the inputs
            var binding = new Dictionary<Type, Type>();
            var restrictions = new Dictionary<DynamicMetaObject, BindingRestrictions>();
            bool noMethod = false;
            foreach (Type t in genArgs) {
                ArgumentInputs inps;
                if (!inputs.TryGetValue(t, out inps)) {
                    continue;
                }

                Type bestType = inps.GetBestType(candidate.Method.Resolver, binding, restrictions);
                if (bestType == null) {
                    // we conflict with possible constraints
                    noMethod = true;
                    break;
                }
            }

            if (!noMethod) {
                // finally build a new MethodCandidate for the generic method
                genArgs = GetGenericArgumentsForInferedMethod(target, binding);
                if (genArgs == null) {
                    // not all types we're inferred
                    return null;
                }
                
                OverloadInfo newMethod = target.MakeGenericMethod(genArgs);

                List<ParameterWrapper> newWrappers = CreateNewWrappers(candidate.Method, newMethod, target);

                List<ArgBuilder> argBuilders = CreateNewArgBuilders(candidate.Method, newMethod);
                if (argBuilders == null) {
                    // one or more arg builders don't support type inference
                    return null;
                }

                if (restrictions.Count == 0) {
                    restrictions = null;
                }

                // create the new method candidate
                return candidate.Method.ReplaceMethod(newMethod, newWrappers, argBuilders, restrictions);
            }

            return null;
        }
Example #4
0
        /// <summary>
        /// Resolves a method overload and returns back a BindingTarget.
        /// 
        /// The BindingTarget can then be tested for the success or particular type of
        /// failure that prevents the method from being called. If successfully bound the BindingTarget
        /// contains a list of argument meta-objects with additional restrictions that ensure the selection
        /// of the particular overload.
        /// </summary>
        public BindingTarget ResolveOverload(string methodName, IList<MethodBase> methods, NarrowingLevel minLevel, NarrowingLevel maxLevel) {
            ContractUtils.RequiresNotNullItems(methods, "methods");
            ContractUtils.Requires(minLevel <= maxLevel);

            if (_candidateSets != null) {
                throw new InvalidOperationException("Overload resolver cannot be reused.");
            }

            _methodName = methodName;
            _minLevel = minLevel;
            _maxLevel = maxLevel;
            
            // step 1:
            IList<DynamicMetaObject> namedArgs;
            GetNamedArguments(out namedArgs, out _argNames);
            
            // uses arg names:
            BuildCandidateSets(methods);

            // uses target sets:
            int preSplatLimit, postSplatLimit;
            GetSplatLimits(out preSplatLimit, out postSplatLimit);

            // step 2:
            _actualArguments = CreateActualArguments(namedArgs, _argNames, preSplatLimit, postSplatLimit);
            if (_actualArguments == null) {
                return new BindingTarget(methodName, BindingResult.InvalidArguments);
            }

            // steps 3, 4:
            var candidateSet = GetCandidateSet();
            if (candidateSet != null && !candidateSet.IsParamsDictionaryOnly()) {
                return MakeBindingTarget(candidateSet);
            }

            // step 5:
            return new BindingTarget(methodName, _actualArguments.VisibleCount, GetExpectedArgCounts());
        }
Example #5
0
 private static List<DynamicMetaObject> GetAllArguments(ApplicableCandidate candidate, ActualArguments actualArgs) {
     List<DynamicMetaObject> args = new List<DynamicMetaObject>();
     for (int i = 0; i < actualArgs.Count; i++) {
         int index = candidate.ArgumentBinding.ArgumentToParameter(i);
         if (index < actualArgs.Arguments.Count) {
             args.Add(actualArgs.Arguments[index]);
         } else {
             args.Add(actualArgs.NamedArguments[index - actualArgs.Arguments.Count]);
         }
     }
     return args;
 }