/// <summary> /// Bind this function call token as a Uri function /// </summary> /// <param name="functionCallToken">the function call token to bind</param> /// <param name="argumentNodes">list of semantically bound arguments</param> /// <returns>A function call node bound to this function.</returns> private QueryNode BindAsUriFunction(FunctionCallToken functionCallToken, List <QueryNode> argumentNodes) { if (functionCallToken.Source != null) { // the parent must be null for a Uri function. throw new ODataException(ODataErrorStrings.FunctionCallBinder_UriFunctionMustHaveHaveNullParent(functionCallToken.Name)); } string functionCallTokenName = this.state.Configuration.EnableCaseInsensitiveUriFunctionIdentifier ? functionCallToken.Name.ToLowerInvariant() : functionCallToken.Name; // There are some functions (IsOf and Cast for example) that don't necessarily need to be bound to a function signature, // for these, we just Bind them directly to a SingleValueFunctionCallNode if (IsUnboundFunction(functionCallTokenName)) { return(CreateUnboundFunctionNode(functionCallTokenName, argumentNodes)); } // Do some validation and get potential Uri functions that could match what we saw FunctionSignatureWithReturnType[] signatures = GetUriFunctionSignatures(functionCallTokenName); SingleValueNode[] argumentNodeArray = ValidateArgumentsAreSingleValue(functionCallTokenName, argumentNodes); FunctionSignatureWithReturnType signature = MatchSignatureToUriFunction(functionCallTokenName, argumentNodeArray, signatures); if (signature.ReturnType != null) { TypePromoteArguments(signature, argumentNodes); } IEdmTypeReference returnType = signature.ReturnType; return(new SingleValueFunctionCallNode(functionCallTokenName, new ReadOnlyCollection <QueryNode>(argumentNodes), returnType)); }