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); }
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); }
private BindingTarget MakeSuccessfulBindingTarget(ApplicableCandidate result, List<ApplicableCandidate> potentialCandidates, NarrowingLevel level, CandidateSet targetSet) { return new BindingTarget( _methodName, _actualArguments.VisibleCount, result.Method, level, GetRestrictedArgs(result, potentialCandidates, targetSet.Arity) ); }
internal protected virtual Candidate CompareEquivalentCandidates(ApplicableCandidate one, ApplicableCandidate two) { Candidate ret = CompareEquivalentParameters(one.Method, two.Method); if (ret.Chosen()) { return ret; } return Candidate.Equivalent; }
private Candidate GetPreferredParameters(ApplicableCandidate one, ApplicableCandidate two, NarrowingLevel level) { Debug.Assert(one.Method.ParameterCount == two.Method.ParameterCount); var args = GetActualArguments(); Candidate result = Candidate.Equivalent; for (int i = 0; i < args.Count; i++) { Candidate preferred = GetPreferredParameter(one.GetParameter(i), two.GetParameter(i), args[i], level); switch (result) { case Candidate.Equivalent: result = preferred; break; case Candidate.One: if (preferred == Candidate.Two) return Candidate.Ambiguous; break; case Candidate.Two: if (preferred == Candidate.One) return Candidate.Ambiguous; break; case Candidate.Ambiguous: if (preferred != Candidate.Equivalent) { result = preferred; } break; default: throw new InvalidOperationException(); } } // TODO: process collapsed arguments: return result; }
private bool IsBest(ApplicableCandidate candidate, List<ApplicableCandidate> candidates, NarrowingLevel level) { foreach (ApplicableCandidate other in candidates) { if (candidate == other) { continue; } if (GetPreferredCandidate(candidate, other, level) != Candidate.One) { return false; } } return true; }
internal Candidate GetPreferredCandidate(ApplicableCandidate one, ApplicableCandidate two, NarrowingLevel level) { Candidate cmpParams = GetPreferredParameters(one, two, level); if (cmpParams.Chosen()) { return cmpParams; } return CompareEquivalentCandidates(one, two); }
private RestrictedArguments GetRestrictedArgs(ApplicableCandidate selectedCandidate, IList<ApplicableCandidate> candidates, int targetSetSize) { Debug.Assert(selectedCandidate.Method.ParameterCount == _actualArguments.Count); int argCount = _actualArguments.Count; var restrictedArgs = new DynamicMetaObject[argCount]; var types = new Type[argCount]; bool hasAdditionalRestrictions = false; for (int i = 0; i < argCount; i++) { var arg = _actualArguments[i]; if (targetSetSize > 0 && IsOverloadedOnParameter(i, argCount, candidates) || !selectedCandidate.GetParameter(i).Type.IsAssignableFrom(arg.Expression.Type)) { restrictedArgs[i] = RestrictArgument(arg, selectedCandidate.GetParameter(i)); types[i] = arg.GetLimitType(); } else { restrictedArgs[i] = arg; } BindingRestrictions additionalRestrictions; if (selectedCandidate.Method.Restrictions != null && selectedCandidate.Method.Restrictions.TryGetValue(arg, out additionalRestrictions)) { hasAdditionalRestrictions = true; restrictedArgs[i] = new DynamicMetaObject(restrictedArgs[i].Expression, restrictedArgs[i].Restrictions.Merge(additionalRestrictions)); } } return new RestrictedArguments(restrictedArgs, types, hasAdditionalRestrictions); }
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; }
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; }
internal protected override Candidate CompareEquivalentCandidates(ApplicableCandidate one, ApplicableCandidate two) { var result = base.CompareEquivalentCandidates(one, two); if (result.Chosen()) { return result; } if (one.Method.Overload.IsStatic && !two.Method.Overload.IsStatic) { return _callType == CallTypes.ImplicitInstance ? Candidate.Two : Candidate.One; } else if (!one.Method.Overload.IsStatic && two.Method.Overload.IsStatic) { return _callType == CallTypes.ImplicitInstance ? Candidate.One : Candidate.Two; } return Candidate.Equivalent; }
private RestrictedArguments GetRestrictedArgs(ApplicableCandidate selectedCandidate, IList<ApplicableCandidate> candidates, int targetSetSize) { Debug.Assert(selectedCandidate.Method.ParameterCount == _actualArguments.Count); int argCount = _actualArguments.Count; var restrictedArgs = new DynamicMetaObject[argCount]; var types = new Type[argCount]; for (int i = 0; i < argCount; i++) { var arg = _actualArguments[i]; if (targetSetSize > 0 && IsOverloadedOnParameter(i, argCount, candidates) || !selectedCandidate.GetParameter(i).Type.IsAssignableFrom(arg.Expression.Type)) { restrictedArgs[i] = RestrictArgument(arg, selectedCandidate.GetParameter(i)); types[i] = arg.GetLimitType(); } else { restrictedArgs[i] = arg; } } return new RestrictedArguments(restrictedArgs, types); }