internal static Dictionary <string, FunctionDescription[]> CreateFunctions() { Dictionary <string, FunctionDescription[]> dictionary = new Dictionary <string, FunctionDescription[]>(StringComparer.Ordinal); dictionary.Add("endswith", new FunctionDescription[] { StringInstanceFunction("EndsWith", new Type[] { typeof(string) }) }); dictionary.Add("indexof", new FunctionDescription[] { StringInstanceFunction("IndexOf", new Type[] { typeof(string) }) }); dictionary.Add("replace", new FunctionDescription[] { StringInstanceFunction("Replace", new Type[] { typeof(string), typeof(string) }) }); dictionary.Add("startswith", new FunctionDescription[] { StringInstanceFunction("StartsWith", new Type[] { typeof(string) }) }); dictionary.Add("tolower", new FunctionDescription[] { StringInstanceFunction("ToLower", Type.EmptyTypes) }); dictionary.Add("toupper", new FunctionDescription[] { StringInstanceFunction("ToUpper", Type.EmptyTypes) }); dictionary.Add("trim", new FunctionDescription[] { StringInstanceFunction("Trim", Type.EmptyTypes) }); FunctionDescription[] descriptionArray = new FunctionDescription[] { StringInstanceFunction("Substring", new Type[] { typeof(int) }), StringInstanceFunction("Substring", new Type[] { typeof(int), typeof(int) }) }; dictionary.Add("substring", descriptionArray); descriptionArray = new FunctionDescription[] { new FunctionDescription("SubstringOf", new Type[] { typeof(string), typeof(string) }, new Func <Expression, Expression[], Expression>(FunctionDescription.SubstringOf)) }; dictionary.Add("substringof", descriptionArray); descriptionArray = new FunctionDescription[] { CreateFunctionDescription(typeof(string), false, true, "Concat", new Type[] { typeof(string), typeof(string) }) }; dictionary.Add("concat", descriptionArray); descriptionArray = new FunctionDescription[] { CreateFunctionDescription(typeof(string), true, false, "Length", Type.EmptyTypes) }; dictionary.Add("length", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Year"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Year") }; dictionary.Add("year", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Month"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Month") }; dictionary.Add("month", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Day"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Day") }; dictionary.Add("day", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Hour"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Hour"), CreatePropertyBasedFunction(typeof(TimeSpan), "Hours") }; dictionary.Add("hour", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Minute"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Minute"), CreatePropertyBasedFunction(typeof(TimeSpan), "Minutes") }; dictionary.Add("minute", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Second"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Second"), CreatePropertyBasedFunction(typeof(TimeSpan), "Seconds") }; dictionary.Add("second", descriptionArray); dictionary.Add("round", MathFunctionArray("Round")); dictionary.Add("floor", MathFunctionArray("Floor")); dictionary.Add("ceiling", MathFunctionArray("Ceiling")); descriptionArray = new FunctionDescription[] { new FunctionDescription("isof", new Type[] { typeof(Type) }, new Func <Expression, Expression[], Expression>(FunctionDescription.UnaryIsOf)), new FunctionDescription("isof", new Type[] { typeof(object), typeof(Type) }, new Func <Expression, Expression[], Expression>(FunctionDescription.BinaryIsOf)), new FunctionDescription("isof", new Type[] { typeof(ResourceType) }, new Func <Expression, Expression[], Expression>(FunctionDescription.UnaryIsOfResourceType)), new FunctionDescription("isof", new Type[] { typeof(object), typeof(ResourceType) }, new Func <Expression, Expression[], Expression>(FunctionDescription.BinaryIsOfResourceType)) }; dictionary.Add("isof", descriptionArray); ResourceType[] allPrimitives = ResourceType.PrimitiveResourceTypeMap.AllPrimitives; List <FunctionDescription> list = new List <FunctionDescription>(allPrimitives.Length + 4); for (int i = 0; i < allPrimitives.Length; i++) { list.Add(new FunctionDescription("cast", new Type[] { allPrimitives[i].InstanceType, typeof(Type) }, new Func <Expression, Expression[], Expression>(FunctionDescription.BinaryCast))); } list.Add(new FunctionDescription("cast", new Type[] { typeof(Type) }, new Func <Expression, Expression[], Expression>(FunctionDescription.UnaryCast))); list.Add(new FunctionDescription("cast", new Type[] { typeof(object), typeof(Type) }, new Func <Expression, Expression[], Expression>(FunctionDescription.BinaryCast))); list.Add(new FunctionDescription("cast", new Type[] { typeof(ResourceType) }, new Func <Expression, Expression[], Expression>(FunctionDescription.UnaryCastResourceType))); list.Add(new FunctionDescription("cast", new Type[] { typeof(object), typeof(ResourceType) }, new Func <Expression, Expression[], Expression>(FunctionDescription.BinaryCastResourceType))); dictionary.Add("cast", list.ToArray()); List <FunctionDescription> list2 = new List <FunctionDescription> { CreateFunctionDescription(typeof(GeographyOperationsExtensions), false, true, "Distance", new Type[] { typeof(GeographyPoint), typeof(GeographyPoint) }), CreateFunctionDescription(typeof(GeometryOperationsExtensions), false, true, "Distance", new Type[] { typeof(GeometryPoint), typeof(GeometryPoint) }) }; foreach (FunctionDescription description in list2) { description.RequiresNullPropagation = false; } dictionary.Add("geo.distance", list2.ToArray()); return(dictionary); }
/// <summary>Creates a new function description for a method or property.</summary> /// <param name="targetType">Type on which property or method is declared.</param> /// <param name="instance">Whether an instance member is looked for.</param> /// <param name="method">Whether a method (rather than a property) is looked for.</param> /// <param name="name">Name of member.</param> /// <param name="parameterTypes">Parameter types.</param> /// <returns>A new function description.</returns> private static FunctionDescription CreateFunctionDescription( Type targetType, bool instance, bool method, string name, params Type[] parameterTypes) { Debug.Assert(targetType != null, "targetType != null"); Debug.Assert(name != null, "name != null"); Debug.Assert(parameterTypes.Length == 0 || method, "parameterTypes.Length == 0 || method"); Debug.Assert(method || instance, "method || instance"); BindingFlags flags = BindingFlags.Public | (instance ? BindingFlags.Instance : BindingFlags.Static); MemberInfo member; if (method) { member = targetType.GetMethod(name, flags, null, parameterTypes, null); Debug.Assert(member != null, "methodInfo != null"); } else { member = targetType.GetProperty(name, flags); Debug.Assert(member != null, "propertyInfo != null"); } Type[] functionParameterTypes; if (instance) { functionParameterTypes = new Type[parameterTypes.Length + 1]; functionParameterTypes[0] = targetType; parameterTypes.CopyTo(functionParameterTypes, 1); } else { functionParameterTypes = parameterTypes; } FunctionDescription result = new FunctionDescription(member, functionParameterTypes); if (method) { if (instance) { result.ConversionFunction = new Func <Expression, Expression[], Expression>(result.InstanceMethodConversionFunction); } else { result.ConversionFunction = new Func <Expression, Expression[], Expression>(result.StaticMethodConversionFunction); } } else { Debug.Assert(instance, "instance"); result.ConversionFunction = new Func <Expression, Expression[], Expression>(result.InstancePropertyConversionFunction); } return(result); }
private static FunctionDescription CreateFunctionDescription(Type targetType, bool instance, bool method, string name, params Type[] parameterTypes) { MemberInfo property; Type[] typeArray; BindingFlags bindingAttr = BindingFlags.Public | (instance ? BindingFlags.Instance : BindingFlags.Static); if (method) { property = targetType.GetMethod(name, bindingAttr, null, parameterTypes, null); } else { property = targetType.GetProperty(name, bindingAttr); } if (instance) { typeArray = new Type[parameterTypes.Length + 1]; typeArray[0] = targetType; parameterTypes.CopyTo(typeArray, 1); } else { typeArray = parameterTypes; } FunctionDescription description = new FunctionDescription(property, typeArray); if (method) { if (instance) { description.ConversionFunction = new Func <Expression, Expression[], Expression>(description.InstanceMethodConversionFunction); return(description); } description.ConversionFunction = new Func <Expression, Expression[], Expression>(description.StaticMethodConversionFunction); return(description); } description.ConversionFunction = new Func <Expression, Expression[], Expression>(description.InstancePropertyConversionFunction); return(description); }
/// <summary>Creates a new function description for a method or property.</summary> /// <param name="targetType">Type on which property or method is declared.</param> /// <param name="instance">Whether an instance member is looked for.</param> /// <param name="method">Whether a method (rather than a property) is looked for.</param> /// <param name="name">Name of member.</param> /// <param name="parameterTypes">Parameter types.</param> /// <returns>A new function description.</returns> private static FunctionDescription CreateFunctionDescription( Type targetType, bool instance, bool method, string name, params Type[] parameterTypes) { Debug.Assert(targetType != null, "targetType != null"); Debug.Assert(name != null, "name != null"); Debug.Assert(parameterTypes.Length == 0 || method, "parameterTypes.Length == 0 || method"); Debug.Assert(method || instance, "method || instance"); BindingFlags flags = BindingFlags.Public | (instance ? BindingFlags.Instance : BindingFlags.Static); MemberInfo member; if (method) { member = targetType.GetMethod(name, flags, null, parameterTypes, null); Debug.Assert(member != null, "methodInfo != null"); } else { member = targetType.GetProperty(name, flags); Debug.Assert(member != null, "propertyInfo != null"); } Type[] functionParameterTypes; if (instance) { functionParameterTypes = new Type[parameterTypes.Length + 1]; functionParameterTypes[0] = targetType; parameterTypes.CopyTo(functionParameterTypes, 1); } else { functionParameterTypes = parameterTypes; } FunctionDescription result = new FunctionDescription(member, functionParameterTypes); if (method) { if (instance) { result.ConversionFunction = new Func<Expression, Expression[], Expression>(result.InstanceMethodConversionFunction); } else { result.ConversionFunction = new Func<Expression, Expression[], Expression>(result.StaticMethodConversionFunction); } } else { Debug.Assert(instance, "instance"); result.ConversionFunction = new Func<Expression, Expression[], Expression>(result.InstancePropertyConversionFunction); } return result; }
/// <summary>Creates and populates a dictionary of system functions.</summary> /// <returns>A new dictionary of functions.</returns> internal static Dictionary<string, FunctionDescription[]> CreateFunctions() { Dictionary<string, FunctionDescription[]> result = new Dictionary<string, FunctionDescription[]>(StringComparer.Ordinal); // String functions. FunctionDescription[] signatures; result.Add("endswith", new FunctionDescription[] { StringInstanceFunction("EndsWith", typeof(string)) }); result.Add("indexof", new FunctionDescription[] { StringInstanceFunction("IndexOf", typeof(string)) }); result.Add("replace", new FunctionDescription[] { StringInstanceFunction(FunctionNameClrStringReplace, typeof(string), typeof(string)) }); result.Add("startswith", new FunctionDescription[] { StringInstanceFunction("StartsWith", typeof(string)) }); result.Add("tolower", new FunctionDescription[] { StringInstanceFunction("ToLower", Type.EmptyTypes) }); result.Add("toupper", new FunctionDescription[] { StringInstanceFunction("ToUpper", Type.EmptyTypes) }); result.Add("trim", new FunctionDescription[] { StringInstanceFunction("Trim", Type.EmptyTypes) }); signatures = new FunctionDescription[] { StringInstanceFunction("Substring", typeof(int)), StringInstanceFunction("Substring", typeof(int), typeof(int)) }; result.Add("substring", signatures); signatures = new FunctionDescription[] { new FunctionDescription("SubstringOf", new Type[] { typeof(string), typeof(string) }, SubstringOf) }; result.Add("substringof", signatures); signatures = new FunctionDescription[] { CreateFunctionDescription(typeof(string), false /* instance */, true /* method */, "Concat", typeof(string), typeof(string)) }; result.Add("concat", signatures); signatures = new FunctionDescription[] { CreateFunctionDescription(typeof(string), true /* instance */, false /* method */, "Length", Type.EmptyTypes) }; result.Add("length", signatures); // DateTime functions. result.Add("year", DateTimeFunctionArray("Year")); result.Add("month", DateTimeFunctionArray("Month")); result.Add("day", DateTimeFunctionArray("Day")); result.Add("hour", DateTimeFunctionArray("Hour")); result.Add("minute", DateTimeFunctionArray("Minute")); result.Add("second", DateTimeFunctionArray("Second")); // Mathematical functions. result.Add("round", MathFunctionArray("Round")); result.Add("floor", MathFunctionArray("Floor")); result.Add("ceiling", MathFunctionArray("Ceiling")); // Type functions. signatures = new FunctionDescription[] { new FunctionDescription(FunctionNameIsOf, new Type[] { typeof(Type) }, FunctionDescription.UnaryIsOf), new FunctionDescription(FunctionNameIsOf, new Type[] { typeof(object), typeof(Type) }, FunctionDescription.BinaryIsOf), new FunctionDescription(FunctionNameIsOf, new Type[] { typeof(ResourceType) }, FunctionDescription.UnaryIsOfResourceType), new FunctionDescription(FunctionNameIsOf, new Type[] { typeof(object), typeof(ResourceType) }, FunctionDescription.BinaryIsOfResourceType), }; result.Add(FunctionNameIsOf, signatures); // For cast() signatures, we need to add all primitive types directly as well as the object (open type) // and unary versions; otherwise expression will convert to object, then again to whatever other type // is required. System.Data.Services.Providers.ResourceType[] primitiveTypes = WebUtil.GetPrimitiveTypes(); List<FunctionDescription> castSignatures = new List<FunctionDescription>(primitiveTypes.Length + 4); for (int i = 0; i < primitiveTypes.Length; i++) { Debug.Assert( primitiveTypes[i].InstanceType != typeof(Type), "primitiveTypes[i].Type != typeof(Type) -- otherwise extra signatures will be added for cast()"); Debug.Assert( primitiveTypes[i].InstanceType != typeof(object), "primitiveTypes[i].Type != typeof(object) -- otherwise extra signatures will be added for cast()"); castSignatures.Add(new FunctionDescription(FunctionNameCast, new Type[] { primitiveTypes[i].InstanceType, typeof(Type) }, FunctionDescription.BinaryCast)); } castSignatures.Add(new FunctionDescription(FunctionNameCast, new Type[] { typeof(Type) }, FunctionDescription.UnaryCast)); castSignatures.Add(new FunctionDescription(FunctionNameCast, new Type[] { typeof(object), typeof(Type) }, FunctionDescription.BinaryCast)); castSignatures.Add(new FunctionDescription(FunctionNameCast, new Type[] { typeof(ResourceType) }, FunctionDescription.UnaryCastResourceType)); castSignatures.Add(new FunctionDescription(FunctionNameCast, new Type[] { typeof(object), typeof(ResourceType) }, FunctionDescription.BinaryCastResourceType)); result.Add(FunctionNameCast, castSignatures.ToArray()); return result; }
/// <summary>Finds the best fitting function for the specified arguments.</summary> /// <param name="functions">Functions to consider.</param> /// <param name="arguments">Arguments; if a best function is found, promoted arguments.</param> /// <returns>The best fitting function; null if none found or ambiguous.</returns> private FunctionDescription FindBestFunction(FunctionDescription[] functions, ref Expression[] arguments) { Debug.Assert(functions != null, "functions != null"); List<FunctionDescription> applicableFunctions = new List<FunctionDescription>(functions.Length); List<Expression[]> applicablePromotedArguments = new List<Expression[]>(functions.Length); // Build a list of applicable functions (and cache their promoted arguments). foreach (FunctionDescription candidate in functions) { if (candidate.ParameterTypes.Length != arguments.Length) { continue; } Expression[] promotedArguments = new Expression[arguments.Length]; bool argumentsMatch = true; for (int i = 0; i < candidate.ParameterTypes.Length; i++) { promotedArguments[i] = this.PromoteExpression(arguments[i], candidate.ParameterTypes[i], true); if (promotedArguments[i] == null) { argumentsMatch = false; break; } } if (argumentsMatch) { applicableFunctions.Add(candidate); applicablePromotedArguments.Add(promotedArguments); } } // Return the best applicable function. if (applicableFunctions.Count == 0) { // No matching function. return null; } else if (applicableFunctions.Count == 1) { arguments = applicablePromotedArguments[0]; return applicableFunctions[0]; } else { // Find a single function which is better than all others. int bestFunctionIndex = -1; for (int i = 0; i < applicableFunctions.Count; i++) { bool betterThanAllOthers = true; for (int j = 0; j < applicableFunctions.Count; j++) { if (i != j && IsBetterThan(arguments, applicableFunctions[j].ParameterTypes, applicableFunctions[i].ParameterTypes)) { betterThanAllOthers = false; break; } } if (betterThanAllOthers) { if (bestFunctionIndex == -1) { bestFunctionIndex = i; } else { // Ambiguous. return null; } } } if (bestFunctionIndex == -1) { return null; } arguments = applicablePromotedArguments[bestFunctionIndex]; return applicableFunctions[bestFunctionIndex]; } }
/// <summary>Creates and populates a dictionary of system functions.</summary> /// <returns>A new dictionary of functions.</returns> internal static Dictionary <string, FunctionDescription[]> CreateFunctions() { Dictionary <string, FunctionDescription[]> result = new Dictionary <string, FunctionDescription[]>(StringComparer.Ordinal); // String functions. FunctionDescription[] signatures; result.Add("endswith", new FunctionDescription[] { StringInstanceFunction("EndsWith", typeof(string)) }); result.Add("indexof", new FunctionDescription[] { StringInstanceFunction("IndexOf", typeof(string)) }); result.Add("replace", new FunctionDescription[] { StringInstanceFunction(FunctionNameClrStringReplace, typeof(string), typeof(string)) }); result.Add("startswith", new FunctionDescription[] { StringInstanceFunction("StartsWith", typeof(string)) }); result.Add("tolower", new FunctionDescription[] { StringInstanceFunction("ToLower", Type.EmptyTypes) }); result.Add("toupper", new FunctionDescription[] { StringInstanceFunction("ToUpper", Type.EmptyTypes) }); result.Add("trim", new FunctionDescription[] { StringInstanceFunction("Trim", Type.EmptyTypes) }); signatures = new FunctionDescription[] { StringInstanceFunction("Substring", typeof(int)), StringInstanceFunction("Substring", typeof(int), typeof(int)) }; result.Add("substring", signatures); signatures = new FunctionDescription[] { new FunctionDescription("SubstringOf", new Type[] { typeof(string), typeof(string) }, SubstringOf) }; result.Add("substringof", signatures); signatures = new FunctionDescription[] { CreateFunctionDescription(typeof(string), false /* instance */, true /* method */, "Concat", typeof(string), typeof(string)) }; result.Add("concat", signatures); signatures = new FunctionDescription[] { CreateFunctionDescription(typeof(string), true /* instance */, false /* method */, "Length", Type.EmptyTypes) }; result.Add("length", signatures); // DateTime functions. result.Add("year", DateTimeFunctionArray("Year")); result.Add("month", DateTimeFunctionArray("Month")); result.Add("day", DateTimeFunctionArray("Day")); result.Add("hour", DateTimeFunctionArray("Hour")); result.Add("minute", DateTimeFunctionArray("Minute")); result.Add("second", DateTimeFunctionArray("Second")); // Mathematical functions. result.Add("round", MathFunctionArray("Round")); result.Add("floor", MathFunctionArray("Floor")); result.Add("ceiling", MathFunctionArray("Ceiling")); // Type functions. signatures = new FunctionDescription[] { new FunctionDescription(FunctionNameIsOf, new Type[] { typeof(Type) }, FunctionDescription.UnaryIsOf), new FunctionDescription(FunctionNameIsOf, new Type[] { typeof(object), typeof(Type) }, FunctionDescription.BinaryIsOf), new FunctionDescription(FunctionNameIsOf, new Type[] { typeof(ResourceType) }, FunctionDescription.UnaryIsOfResourceType), new FunctionDescription(FunctionNameIsOf, new Type[] { typeof(object), typeof(ResourceType) }, FunctionDescription.BinaryIsOfResourceType), }; result.Add(FunctionNameIsOf, signatures); // For cast() signatures, we need to add all primitive types directly as well as the object (open type) // and unary versions; otherwise expression will convert to object, then again to whatever other type // is required. System.Data.Services.Providers.ResourceType[] primitiveTypes = WebUtil.GetPrimitiveTypes(); List <FunctionDescription> castSignatures = new List <FunctionDescription>(primitiveTypes.Length + 4); for (int i = 0; i < primitiveTypes.Length; i++) { Debug.Assert( primitiveTypes[i].InstanceType != typeof(Type), "primitiveTypes[i].Type != typeof(Type) -- otherwise extra signatures will be added for cast()"); Debug.Assert( primitiveTypes[i].InstanceType != typeof(object), "primitiveTypes[i].Type != typeof(object) -- otherwise extra signatures will be added for cast()"); castSignatures.Add(new FunctionDescription(FunctionNameCast, new Type[] { primitiveTypes[i].InstanceType, typeof(Type) }, FunctionDescription.BinaryCast)); } castSignatures.Add(new FunctionDescription(FunctionNameCast, new Type[] { typeof(Type) }, FunctionDescription.UnaryCast)); castSignatures.Add(new FunctionDescription(FunctionNameCast, new Type[] { typeof(object), typeof(Type) }, FunctionDescription.BinaryCast)); castSignatures.Add(new FunctionDescription(FunctionNameCast, new Type[] { typeof(ResourceType) }, FunctionDescription.UnaryCastResourceType)); castSignatures.Add(new FunctionDescription(FunctionNameCast, new Type[] { typeof(object), typeof(ResourceType) }, FunctionDescription.BinaryCastResourceType)); result.Add(FunctionNameCast, castSignatures.ToArray()); return(result); }
internal static Dictionary<string, FunctionDescription[]> CreateFunctions() { Dictionary<string, FunctionDescription[]> dictionary = new Dictionary<string, FunctionDescription[]>(StringComparer.Ordinal); dictionary.Add("endswith", new FunctionDescription[] { StringInstanceFunction("EndsWith", new Type[] { typeof(string) }) }); dictionary.Add("indexof", new FunctionDescription[] { StringInstanceFunction("IndexOf", new Type[] { typeof(string) }) }); dictionary.Add("replace", new FunctionDescription[] { StringInstanceFunction("Replace", new Type[] { typeof(string), typeof(string) }) }); dictionary.Add("startswith", new FunctionDescription[] { StringInstanceFunction("StartsWith", new Type[] { typeof(string) }) }); dictionary.Add("tolower", new FunctionDescription[] { StringInstanceFunction("ToLower", Type.EmptyTypes) }); dictionary.Add("toupper", new FunctionDescription[] { StringInstanceFunction("ToUpper", Type.EmptyTypes) }); dictionary.Add("trim", new FunctionDescription[] { StringInstanceFunction("Trim", Type.EmptyTypes) }); FunctionDescription[] descriptionArray = new FunctionDescription[] { StringInstanceFunction("Substring", new Type[] { typeof(int) }), StringInstanceFunction("Substring", new Type[] { typeof(int), typeof(int) }) }; dictionary.Add("substring", descriptionArray); descriptionArray = new FunctionDescription[] { new FunctionDescription("SubstringOf", new Type[] { typeof(string), typeof(string) }, new Func<Expression, Expression[], Expression>(FunctionDescription.SubstringOf)) }; dictionary.Add("substringof", descriptionArray); descriptionArray = new FunctionDescription[] { CreateFunctionDescription(typeof(string), false, true, "Concat", new Type[] { typeof(string), typeof(string) }) }; dictionary.Add("concat", descriptionArray); descriptionArray = new FunctionDescription[] { CreateFunctionDescription(typeof(string), true, false, "Length", Type.EmptyTypes) }; dictionary.Add("length", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Year"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Year") }; dictionary.Add("year", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Month"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Month") }; dictionary.Add("month", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Day"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Day") }; dictionary.Add("day", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Hour"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Hour"), CreatePropertyBasedFunction(typeof(TimeSpan), "Hours") }; dictionary.Add("hour", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Minute"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Minute"), CreatePropertyBasedFunction(typeof(TimeSpan), "Minutes") }; dictionary.Add("minute", descriptionArray); descriptionArray = new FunctionDescription[] { CreatePropertyBasedFunction(typeof(DateTime), "Second"), CreatePropertyBasedFunction(typeof(DateTimeOffset), "Second"), CreatePropertyBasedFunction(typeof(TimeSpan), "Seconds") }; dictionary.Add("second", descriptionArray); dictionary.Add("round", MathFunctionArray("Round")); dictionary.Add("floor", MathFunctionArray("Floor")); dictionary.Add("ceiling", MathFunctionArray("Ceiling")); descriptionArray = new FunctionDescription[] { new FunctionDescription("isof", new Type[] { typeof(Type) }, new Func<Expression, Expression[], Expression>(FunctionDescription.UnaryIsOf)), new FunctionDescription("isof", new Type[] { typeof(object), typeof(Type) }, new Func<Expression, Expression[], Expression>(FunctionDescription.BinaryIsOf)), new FunctionDescription("isof", new Type[] { typeof(ResourceType) }, new Func<Expression, Expression[], Expression>(FunctionDescription.UnaryIsOfResourceType)), new FunctionDescription("isof", new Type[] { typeof(object), typeof(ResourceType) }, new Func<Expression, Expression[], Expression>(FunctionDescription.BinaryIsOfResourceType)) }; dictionary.Add("isof", descriptionArray); ResourceType[] allPrimitives = ResourceType.PrimitiveResourceTypeMap.AllPrimitives; List<FunctionDescription> list = new List<FunctionDescription>(allPrimitives.Length + 4); for (int i = 0; i < allPrimitives.Length; i++) { list.Add(new FunctionDescription("cast", new Type[] { allPrimitives[i].InstanceType, typeof(Type) }, new Func<Expression, Expression[], Expression>(FunctionDescription.BinaryCast))); } list.Add(new FunctionDescription("cast", new Type[] { typeof(Type) }, new Func<Expression, Expression[], Expression>(FunctionDescription.UnaryCast))); list.Add(new FunctionDescription("cast", new Type[] { typeof(object), typeof(Type) }, new Func<Expression, Expression[], Expression>(FunctionDescription.BinaryCast))); list.Add(new FunctionDescription("cast", new Type[] { typeof(ResourceType) }, new Func<Expression, Expression[], Expression>(FunctionDescription.UnaryCastResourceType))); list.Add(new FunctionDescription("cast", new Type[] { typeof(object), typeof(ResourceType) }, new Func<Expression, Expression[], Expression>(FunctionDescription.BinaryCastResourceType))); dictionary.Add("cast", list.ToArray()); List<FunctionDescription> list2 = new List<FunctionDescription> { CreateFunctionDescription(typeof(GeographyOperationsExtensions), false, true, "Distance", new Type[] { typeof(GeographyPoint), typeof(GeographyPoint) }), CreateFunctionDescription(typeof(GeometryOperationsExtensions), false, true, "Distance", new Type[] { typeof(GeometryPoint), typeof(GeometryPoint) }) }; foreach (FunctionDescription description in list2) { description.RequiresNullPropagation = false; } dictionary.Add("geo.distance", list2.ToArray()); return dictionary; }
private static FunctionDescription CreateFunctionDescription(Type targetType, bool instance, bool method, string name, params Type[] parameterTypes) { MemberInfo property; Type[] typeArray; BindingFlags bindingAttr = BindingFlags.Public | (instance ? BindingFlags.Instance : BindingFlags.Static); if (method) { property = targetType.GetMethod(name, bindingAttr, null, parameterTypes, null); } else { property = targetType.GetProperty(name, bindingAttr); } if (instance) { typeArray = new Type[parameterTypes.Length + 1]; typeArray[0] = targetType; parameterTypes.CopyTo(typeArray, 1); } else { typeArray = parameterTypes; } FunctionDescription description = new FunctionDescription(property, typeArray); if (method) { if (instance) { description.ConversionFunction = new Func<Expression, Expression[], Expression>(description.InstanceMethodConversionFunction); return description; } description.ConversionFunction = new Func<Expression, Expression[], Expression>(description.StaticMethodConversionFunction); return description; } description.ConversionFunction = new Func<Expression, Expression[], Expression>(description.InstancePropertyConversionFunction); return description; }