/// <summary> /// Finds the signature that best matches the arguments /// </summary> /// <param name="functionCallToken">The name of the function</param> /// <param name="argumentNodes">The nodes of the arguments, can be new {null,null}.</param> /// <param name="nameSignatures">The name-signature pairs to match against</param> /// <returns>Returns the matching signature or throws</returns> internal static KeyValuePair <string, FunctionSignatureWithReturnType> MatchSignatureToUriFunction(string functionCallToken, SingleValueNode[] argumentNodes, IList <KeyValuePair <string, FunctionSignatureWithReturnType> > nameSignatures) { KeyValuePair <string, FunctionSignatureWithReturnType> nameSignature; IEdmTypeReference[] argumentTypes = argumentNodes.Select(s => s.TypeReference).ToArray(); // Handle the cases where we don't have type information (null literal, open properties) for ANY of the arguments int argumentCount = argumentTypes.Length; if (argumentTypes.All(a => a == null) && argumentCount > 0) { // we specifically want to find just the first function that matches the number of arguments, we don't care about // ambiguity here because we're already in an ambiguous case where we don't know what kind of types // those arguments are. KeyValuePair <string, FunctionSignatureWithReturnType> found = nameSignatures.FirstOrDefault(pair => pair.Value.ArgumentTypes.Length == argumentCount); if (found.Equals(TypePromotionUtils.NotFoundKeyValuePair)) { throw new ODataException(ODataErrorStrings.FunctionCallBinder_CannotFindASuitableOverload(functionCallToken, argumentTypes.Length)); } else { // in this case we can't assert the return type, we can only assert that a function exists... so // we need to set the return type to null. nameSignature = new KeyValuePair <string, FunctionSignatureWithReturnType>( found.Key, new FunctionSignatureWithReturnType(null, found.Value.ArgumentTypes)); } } else { nameSignature = TypePromotionUtils.FindBestFunctionSignature(nameSignatures, argumentNodes, functionCallToken); if (nameSignature.Equals(TypePromotionUtils.NotFoundKeyValuePair)) { throw new ODataException(ODataErrorStrings.MetadataBinder_NoApplicableFunctionFound( functionCallToken, UriFunctionsHelper.BuildFunctionSignatureListDescription(functionCallToken, nameSignatures.Select(sig => sig.Value)))); } } return(nameSignature); }
/// <summary> /// Finds the signature that best matches the arguments /// </summary> /// <param name="functionName">The name of the function</param> /// <param name="argumentNodes">The nodes of the arguments, can be new {null,null}.</param> /// <param name="signatures">The signatures to match against</param> /// <returns>Returns the matching signature or throws</returns> internal static FunctionSignatureWithReturnType MatchSignatureToUriFunction(string functionName, SingleValueNode[] argumentNodes, FunctionSignatureWithReturnType[] signatures) { FunctionSignatureWithReturnType signature; IEdmTypeReference[] argumentTypes = argumentNodes.Select(s => s.TypeReference).ToArray(); // Handle the cases where we don't have type information (null literal, open properties) for ANY of the arguments int argumentCount = argumentTypes.Length; if (argumentTypes.All(a => a == null) && argumentCount > 0) { // we specifically want to find just the first function that matches the number of arguments, we don't care about // ambiguity here because we're already in an ambiguous case where we don't know what kind of types // those arguments are. signature = signatures.FirstOrDefault(candidateFunction => candidateFunction.ArgumentTypes.Count() == argumentCount); if (signature == null) { throw new ODataException(ODataErrorStrings.FunctionCallBinder_CannotFindASuitableOverload(functionName, argumentTypes.Count())); } else { // in this case we can't assert the return type, we can only assert that a function exists... so // we need to set the return type to null. signature = new FunctionSignatureWithReturnType(null, signature.ArgumentTypes); } } else { signature = TypePromotionUtils.FindBestFunctionSignature(signatures, argumentNodes); if (signature == null) { throw new ODataException(ODataErrorStrings.MetadataBinder_NoApplicableFunctionFound( functionName, UriFunctionsHelper.BuildFunctionSignatureListDescription(functionName, signatures))); } } return(signature); }