Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataWeb / Server / System / Data / Services / Parsing / FunctionDescription.cs / 1 / FunctionDescription.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Provides a class to represent system functions.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Parsing
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
/// Use this class to represent a system function for Astoria expressions.
[DebuggerDisplay("FunctionDescription {name}")]
internal class FunctionDescription
{
/// Function name for type casts.
private const string FunctionNameCast = "cast";
/// Function name for type checks.
private const string FunctionNameIsOf = "isof";
/// CLR member for property or method invocation.
private readonly MemberInfo member;
/// Function name.
private readonly string name;
/// Parameter types for method invocation.
private readonly Type[] parameterTypes;
/// Conversion to expression for this function.
private Func conversionFunction;
/// Initializes a new .
/// CLR member for property or method invocation.
/// Parameter types for method invocation.
public FunctionDescription(MemberInfo member, Type[] parameterTypes)
: this(member, parameterTypes, null, member.Name)
{
}
/// Initializes a new .
/// Name for conversion function.
/// Parameter types for method invocation.
/// Conversion to expression for this function.
public FunctionDescription(string name, Type[] parameterTypes, Func conversionFunction)
: this(null, parameterTypes, conversionFunction, name)
{
}
/// Initializes a new .
/// CLR member for property or method invocation.
/// Parameter types for method invocation.
/// Conversion to expression for this function.
/// Name for conversion function.
private FunctionDescription(
MemberInfo member,
Type[] parameterTypes,
Func conversionFunction,
string name)
{
this.member = member;
this.parameterTypes = parameterTypes;
this.conversionFunction = conversionFunction;
this.name = name;
}
/// Conversion to expression for this function.
public Func ConversionFunction
{
[DebuggerStepThrough]
get { return this.conversionFunction; }
[DebuggerStepThrough]
set { this.conversionFunction = value; }
}
/// Gets a value indicating whether this function is a typecast function.
public bool IsTypeCast
{
get { return this.name == FunctionNameCast; }
}
/// Gets a value indicating whether this function is a type check function.
public bool IsTypeCheck
{
get { return this.name == FunctionNameIsOf; }
}
/// Parameter types for method invocation.
public Type[] ParameterTypes
{
[DebuggerStepThrough]
get { return this.parameterTypes; }
}
/// Performs an instance method invocation.
/// "it" expression; unused by this function.
/// Arguments for method invocation; first one should be the target 'this'.
/// A new expression with the method invocation.
public Expression InstanceMethodConvertionFunction(Expression target, Expression[] arguments)
{
Expression instanceArgument = arguments[0];
Expression[] methodArguments = new Expression[arguments.Length - 1];
Array.Copy(arguments, 1, methodArguments, 0, arguments.Length - 1);
return Expression.Call(instanceArgument, (MethodInfo)this.member, methodArguments);
}
/// Performs a static method invocation.
/// "it" expression; unused by this function.
/// Arguments for method invocation.
/// A new expression with the method invocation.
public Expression StaticMethodConvertionFunction(Expression target, Expression[] arguments)
{
return Expression.Call((MethodInfo)this.member, arguments);
}
/// Performs an instance property access.
/// "it" expression; unused by this function.
/// Argument for property access; instance.
/// A new expression with the property access.
public Expression InstancePropertyConvertionFunction(Expression target, Expression[] arguments)
{
return Expression.Property(arguments[0], (PropertyInfo)this.member);
}
/// Builds a list of function signatures.
/// Function name.
/// Function descriptions.
/// A string with ';'-separated list of function signatures.
internal static string BuildSignatureList(string name, IEnumerable descriptions)
{
System.Text.StringBuilder builder = new System.Text.StringBuilder();
string descriptionSeparator = "";
foreach (FunctionDescription description in descriptions)
{
builder.Append(descriptionSeparator);
descriptionSeparator = "; ";
string parameterSeparator = "";
builder.Append(name);
builder.Append('(');
foreach (Type type in description.ParameterTypes)
{
builder.Append(parameterSeparator);
parameterSeparator = ", ";
Type underlyingType = Nullable.GetUnderlyingType(type);
if (underlyingType != null)
{
builder.Append(underlyingType.FullName);
builder.Append('?');
}
else
{
builder.Append(type.FullName);
}
}
builder.Append(')');
}
return builder.ToString();
}
/// Creates and populates a dictionary of system functions.
/// A new dictionary of functions.
internal static Dictionary CreateFunctions()
{
Dictionary result = new Dictionary(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("Replace", 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) }, new Func(FunctionDescription.UnaryIsOf)),
new FunctionDescription(FunctionNameIsOf, new Type[] { typeof(object), typeof(Type) }, new Func(FunctionDescription.BinaryIsOf)),
};
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 castSignatures = new List(2 + primitiveTypes.Length * 2);
for (int i = 0; i < primitiveTypes.Length; i++)
{
Debug.Assert(
primitiveTypes[i].Type != typeof(Type),
"primitiveTypes[i].Type != typeof(Type) -- otherwise extra signatures will be added for cast()");
Debug.Assert(
primitiveTypes[i].Type != typeof(object),
"primitiveTypes[i].Type != typeof(object) -- otherwise extra signatures will be added for cast()");
castSignatures.Add(new FunctionDescription(
FunctionNameCast,
new Type[] { primitiveTypes[i].Type, typeof(Type) },
new Func(FunctionDescription.BinaryCast)));
if (primitiveTypes[i].Type.IsValueType)
{
castSignatures.Add(new FunctionDescription(
FunctionNameCast,
new Type[] { typeof(Nullable<>).MakeGenericType(primitiveTypes[i].Type), typeof(Type) },
new Func(FunctionDescription.BinaryCast)));
}
}
castSignatures.Add(
new FunctionDescription(FunctionNameCast, new Type[] { typeof(Type) }, FunctionDescription.UnaryCast));
castSignatures.Add(
new FunctionDescription(FunctionNameCast, new Type[] { typeof(object), typeof(Type) }, new Func(FunctionDescription.BinaryCast)));
result.Add(FunctionNameCast, castSignatures.ToArray());
return result;
}
/// Transforms a URI-style "substringof(a,b)" function into "a.contains(b)".
/// Target of query; not used.
/// Arguments to function.
/// The conversion for this method.
internal static Expression SubstringOf(Expression target, Expression[] arguments)
{
Debug.Assert(arguments != null, "arguments != null");
Debug.Assert(arguments.Length == 2, "arguments.Length == 2");
BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
Type[] parameterTypes = new Type[] { typeof(string) };
MethodInfo method = typeof(string).GetMethod("Contains", flags, null, parameterTypes, null);
Debug.Assert(method != null, "method != null -- otherwise couldn't find string.Contains(string)");
return Expression.Call(arguments[1], method, arguments[0]);
}
/// Performs a type check for the "it" expression.
/// "it" expression.
/// Argument for type check; type.
/// A new expression with the type check.
internal static Expression UnaryIsOf(Expression target, Expression[] arguments)
{
ConstantExpression ce = (ConstantExpression)arguments[0];
return Expression.TypeIs(target, (Type)ce.Value);
}
/// Performs a type check for a given expression.
/// "it" expression; unused by this function.
/// Arguments for type check; instance and type.
/// A new expression with the type check.
internal static Expression BinaryIsOf(Expression target, Expression[] arguments)
{
ConstantExpression ce = (ConstantExpression)arguments[1];
return Expression.TypeIs(arguments[0], (Type)ce.Value);
}
/// Performs a cast for the "it" expression.
/// "it" expression.
/// Argument for cast; type.
/// A new expression with the cast.
internal static Expression UnaryCast(Expression target, Expression[] arguments)
{
Debug.Assert(arguments.Length == 1, "arguments.Length == 1");
ConstantExpression ce = (ConstantExpression)arguments[0];
return Expression.Convert(target, (Type)ce.Value);
}
/// Performs a cast for a given expression.
/// "it" expression; unused by this function.
/// Arguments for cast; instance and type.
/// A new expression with the cast.
internal static Expression BinaryCast(Expression target, Expression[] arguments)
{
Debug.Assert(arguments.Length == 2, "arguments.Length == 2");
ConstantExpression ce = (ConstantExpression)arguments[1];
// Work around for SQLBUDT #615702 - Protocol: exception thrown in XML with filter=null
//
// We need this in place so we can recognize null constant reliably and generate
// trees that work for both LINQ to Entities and LINQ to Objects for the cases where
// conversions of null literals generate expressions that don't guard for nulls in the
// EF case, but EF ends up calling them anyway because they can be evaluated on the client.
Type targetType = (Type)ce.Value;
if (RequestQueryParser.IsNullConstant(arguments[0]))
{
targetType = RequestQueryParser.GetTypeAllowingNull(targetType);
return Expression.Constant(null, targetType);
}
return Expression.Convert(arguments[0], targetType);
}
/// Creates a new function description for a method or property.
/// Type on which property or method is declared.
/// Whether an instance member is looked for.
/// Whether a method (rather than a property) is looked for.
/// Name of member.
/// Parameter types.
/// A new function description.
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(result.InstanceMethodConvertionFunction);
}
else
{
result.ConversionFunction = new Func(result.StaticMethodConvertionFunction);
}
}
else
{
Debug.Assert(instance, "instance");
result.ConversionFunction = new Func(result.InstancePropertyConvertionFunction);
}
return result;
}
/// Creates a description for a string instance method.
/// Name of method to look up.
/// Parameter types to match.
/// A new function description.
private static FunctionDescription StringInstanceFunction(string name, params Type[] parameterTypes)
{
return CreateFunctionDescription(typeof(string), true /* instance */, true /* method */, name, parameterTypes);
}
/// Creates an array of function description for a DateTime property.
/// Name of property to look up.
/// A new function description array.
private static FunctionDescription[] DateTimeFunctionArray(string name)
{
return new FunctionDescription[]
{
CreateFunctionDescription(typeof(DateTime), true /* instance */, false /* method */, name, Type.EmptyTypes)
};
}
/// Creates an array of function description for math method with decimal and double overloads.
/// Name of method to look up.
/// A new function description array.
private static FunctionDescription[] MathFunctionArray(string name)
{
return new FunctionDescription[]
{
CreateFunctionDescription(typeof(Math), false /* instance */, true /* method */, name, typeof(double)),
CreateFunctionDescription(typeof(Math), false /* instance */, true /* method */, name, typeof(decimal)),
};
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Provides a class to represent system functions.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Parsing
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
/// Use this class to represent a system function for Astoria expressions.
[DebuggerDisplay("FunctionDescription {name}")]
internal class FunctionDescription
{
/// Function name for type casts.
private const string FunctionNameCast = "cast";
/// Function name for type checks.
private const string FunctionNameIsOf = "isof";
/// CLR member for property or method invocation.
private readonly MemberInfo member;
/// Function name.
private readonly string name;
/// Parameter types for method invocation.
private readonly Type[] parameterTypes;
/// Conversion to expression for this function.
private Func conversionFunction;
/// Initializes a new .
/// CLR member for property or method invocation.
/// Parameter types for method invocation.
public FunctionDescription(MemberInfo member, Type[] parameterTypes)
: this(member, parameterTypes, null, member.Name)
{
}
/// Initializes a new .
/// Name for conversion function.
/// Parameter types for method invocation.
/// Conversion to expression for this function.
public FunctionDescription(string name, Type[] parameterTypes, Func conversionFunction)
: this(null, parameterTypes, conversionFunction, name)
{
}
/// Initializes a new .
/// CLR member for property or method invocation.
/// Parameter types for method invocation.
/// Conversion to expression for this function.
/// Name for conversion function.
private FunctionDescription(
MemberInfo member,
Type[] parameterTypes,
Func conversionFunction,
string name)
{
this.member = member;
this.parameterTypes = parameterTypes;
this.conversionFunction = conversionFunction;
this.name = name;
}
/// Conversion to expression for this function.
public Func ConversionFunction
{
[DebuggerStepThrough]
get { return this.conversionFunction; }
[DebuggerStepThrough]
set { this.conversionFunction = value; }
}
/// Gets a value indicating whether this function is a typecast function.
public bool IsTypeCast
{
get { return this.name == FunctionNameCast; }
}
/// Gets a value indicating whether this function is a type check function.
public bool IsTypeCheck
{
get { return this.name == FunctionNameIsOf; }
}
/// Parameter types for method invocation.
public Type[] ParameterTypes
{
[DebuggerStepThrough]
get { return this.parameterTypes; }
}
/// Performs an instance method invocation.
/// "it" expression; unused by this function.
/// Arguments for method invocation; first one should be the target 'this'.
/// A new expression with the method invocation.
public Expression InstanceMethodConvertionFunction(Expression target, Expression[] arguments)
{
Expression instanceArgument = arguments[0];
Expression[] methodArguments = new Expression[arguments.Length - 1];
Array.Copy(arguments, 1, methodArguments, 0, arguments.Length - 1);
return Expression.Call(instanceArgument, (MethodInfo)this.member, methodArguments);
}
/// Performs a static method invocation.
/// "it" expression; unused by this function.
/// Arguments for method invocation.
/// A new expression with the method invocation.
public Expression StaticMethodConvertionFunction(Expression target, Expression[] arguments)
{
return Expression.Call((MethodInfo)this.member, arguments);
}
/// Performs an instance property access.
/// "it" expression; unused by this function.
/// Argument for property access; instance.
/// A new expression with the property access.
public Expression InstancePropertyConvertionFunction(Expression target, Expression[] arguments)
{
return Expression.Property(arguments[0], (PropertyInfo)this.member);
}
/// Builds a list of function signatures.
/// Function name.
/// Function descriptions.
/// A string with ';'-separated list of function signatures.
internal static string BuildSignatureList(string name, IEnumerable descriptions)
{
System.Text.StringBuilder builder = new System.Text.StringBuilder();
string descriptionSeparator = "";
foreach (FunctionDescription description in descriptions)
{
builder.Append(descriptionSeparator);
descriptionSeparator = "; ";
string parameterSeparator = "";
builder.Append(name);
builder.Append('(');
foreach (Type type in description.ParameterTypes)
{
builder.Append(parameterSeparator);
parameterSeparator = ", ";
Type underlyingType = Nullable.GetUnderlyingType(type);
if (underlyingType != null)
{
builder.Append(underlyingType.FullName);
builder.Append('?');
}
else
{
builder.Append(type.FullName);
}
}
builder.Append(')');
}
return builder.ToString();
}
/// Creates and populates a dictionary of system functions.
/// A new dictionary of functions.
internal static Dictionary CreateFunctions()
{
Dictionary result = new Dictionary(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("Replace", 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) }, new Func(FunctionDescription.UnaryIsOf)),
new FunctionDescription(FunctionNameIsOf, new Type[] { typeof(object), typeof(Type) }, new Func(FunctionDescription.BinaryIsOf)),
};
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 castSignatures = new List(2 + primitiveTypes.Length * 2);
for (int i = 0; i < primitiveTypes.Length; i++)
{
Debug.Assert(
primitiveTypes[i].Type != typeof(Type),
"primitiveTypes[i].Type != typeof(Type) -- otherwise extra signatures will be added for cast()");
Debug.Assert(
primitiveTypes[i].Type != typeof(object),
"primitiveTypes[i].Type != typeof(object) -- otherwise extra signatures will be added for cast()");
castSignatures.Add(new FunctionDescription(
FunctionNameCast,
new Type[] { primitiveTypes[i].Type, typeof(Type) },
new Func(FunctionDescription.BinaryCast)));
if (primitiveTypes[i].Type.IsValueType)
{
castSignatures.Add(new FunctionDescription(
FunctionNameCast,
new Type[] { typeof(Nullable<>).MakeGenericType(primitiveTypes[i].Type), typeof(Type) },
new Func(FunctionDescription.BinaryCast)));
}
}
castSignatures.Add(
new FunctionDescription(FunctionNameCast, new Type[] { typeof(Type) }, FunctionDescription.UnaryCast));
castSignatures.Add(
new FunctionDescription(FunctionNameCast, new Type[] { typeof(object), typeof(Type) }, new Func(FunctionDescription.BinaryCast)));
result.Add(FunctionNameCast, castSignatures.ToArray());
return result;
}
/// Transforms a URI-style "substringof(a,b)" function into "a.contains(b)".
/// Target of query; not used.
/// Arguments to function.
/// The conversion for this method.
internal static Expression SubstringOf(Expression target, Expression[] arguments)
{
Debug.Assert(arguments != null, "arguments != null");
Debug.Assert(arguments.Length == 2, "arguments.Length == 2");
BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
Type[] parameterTypes = new Type[] { typeof(string) };
MethodInfo method = typeof(string).GetMethod("Contains", flags, null, parameterTypes, null);
Debug.Assert(method != null, "method != null -- otherwise couldn't find string.Contains(string)");
return Expression.Call(arguments[1], method, arguments[0]);
}
/// Performs a type check for the "it" expression.
/// "it" expression.
/// Argument for type check; type.
/// A new expression with the type check.
internal static Expression UnaryIsOf(Expression target, Expression[] arguments)
{
ConstantExpression ce = (ConstantExpression)arguments[0];
return Expression.TypeIs(target, (Type)ce.Value);
}
/// Performs a type check for a given expression.
/// "it" expression; unused by this function.
/// Arguments for type check; instance and type.
/// A new expression with the type check.
internal static Expression BinaryIsOf(Expression target, Expression[] arguments)
{
ConstantExpression ce = (ConstantExpression)arguments[1];
return Expression.TypeIs(arguments[0], (Type)ce.Value);
}
/// Performs a cast for the "it" expression.
/// "it" expression.
/// Argument for cast; type.
/// A new expression with the cast.
internal static Expression UnaryCast(Expression target, Expression[] arguments)
{
Debug.Assert(arguments.Length == 1, "arguments.Length == 1");
ConstantExpression ce = (ConstantExpression)arguments[0];
return Expression.Convert(target, (Type)ce.Value);
}
/// Performs a cast for a given expression.
/// "it" expression; unused by this function.
/// Arguments for cast; instance and type.
/// A new expression with the cast.
internal static Expression BinaryCast(Expression target, Expression[] arguments)
{
Debug.Assert(arguments.Length == 2, "arguments.Length == 2");
ConstantExpression ce = (ConstantExpression)arguments[1];
// Work around for SQLBUDT #615702 - Protocol: exception thrown in XML with filter=null
//
// We need this in place so we can recognize null constant reliably and generate
// trees that work for both LINQ to Entities and LINQ to Objects for the cases where
// conversions of null literals generate expressions that don't guard for nulls in the
// EF case, but EF ends up calling them anyway because they can be evaluated on the client.
Type targetType = (Type)ce.Value;
if (RequestQueryParser.IsNullConstant(arguments[0]))
{
targetType = RequestQueryParser.GetTypeAllowingNull(targetType);
return Expression.Constant(null, targetType);
}
return Expression.Convert(arguments[0], targetType);
}
/// Creates a new function description for a method or property.
/// Type on which property or method is declared.
/// Whether an instance member is looked for.
/// Whether a method (rather than a property) is looked for.
/// Name of member.
/// Parameter types.
/// A new function description.
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(result.InstanceMethodConvertionFunction);
}
else
{
result.ConversionFunction = new Func(result.StaticMethodConvertionFunction);
}
}
else
{
Debug.Assert(instance, "instance");
result.ConversionFunction = new Func(result.InstancePropertyConvertionFunction);
}
return result;
}
/// Creates a description for a string instance method.
/// Name of method to look up.
/// Parameter types to match.
/// A new function description.
private static FunctionDescription StringInstanceFunction(string name, params Type[] parameterTypes)
{
return CreateFunctionDescription(typeof(string), true /* instance */, true /* method */, name, parameterTypes);
}
/// Creates an array of function description for a DateTime property.
/// Name of property to look up.
/// A new function description array.
private static FunctionDescription[] DateTimeFunctionArray(string name)
{
return new FunctionDescription[]
{
CreateFunctionDescription(typeof(DateTime), true /* instance */, false /* method */, name, Type.EmptyTypes)
};
}
/// Creates an array of function description for math method with decimal and double overloads.
/// Name of method to look up.
/// A new function description array.
private static FunctionDescription[] MathFunctionArray(string name)
{
return new FunctionDescription[]
{
CreateFunctionDescription(typeof(Math), false /* instance */, true /* method */, name, typeof(double)),
CreateFunctionDescription(typeof(Math), false /* instance */, true /* method */, name, typeof(decimal)),
};
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BamlRecordWriter.cs
- FontDifferentiator.cs
- SafeArrayTypeMismatchException.cs
- ThemeDictionaryExtension.cs
- ResXDataNode.cs
- ClientData.cs
- EpmSyndicationContentSerializer.cs
- XamlStream.cs
- DesignRelationCollection.cs
- ReferencedCollectionType.cs
- SoapRpcMethodAttribute.cs
- DbgUtil.cs
- AppSettingsExpressionBuilder.cs
- PerformanceCounterManager.cs
- SetIterators.cs
- PixelShader.cs
- PointAnimationClockResource.cs
- WebPartZone.cs
- StreamingContext.cs
- OperationAbortedException.cs
- DictionaryGlobals.cs
- RuleProcessor.cs
- DataProtection.cs
- PreProcessor.cs
- Token.cs
- HexParser.cs
- CacheForPrimitiveTypes.cs
- ContainerTracking.cs
- IODescriptionAttribute.cs
- StateChangeEvent.cs
- DropShadowEffect.cs
- TreeNodeMouseHoverEvent.cs
- ControlBindingsCollection.cs
- RowToParametersTransformer.cs
- WebPageTraceListener.cs
- DebugController.cs
- RenderData.cs
- TrackingQuery.cs
- SqlBulkCopy.cs
- LockCookie.cs
- BindingMAnagerBase.cs
- MemoryResponseElement.cs
- EncodingTable.cs
- ConditionValidator.cs
- Slider.cs
- XmlnsDefinitionAttribute.cs
- Crc32Helper.cs
- DataColumnCollection.cs
- NameNode.cs
- ConfigurationSchemaErrors.cs
- MimeFormatExtensions.cs
- ping.cs
- CallbackException.cs
- UrlAuthFailureHandler.cs
- TemplateBindingExpressionConverter.cs
- ListComponentEditorPage.cs
- HttpDictionary.cs
- XmlSchemaInferenceException.cs
- DmlSqlGenerator.cs
- PathStreamGeometryContext.cs
- ContextQuery.cs
- BindingValueChangedEventArgs.cs
- XmlAttributeCollection.cs
- CustomPopupPlacement.cs
- GiveFeedbackEventArgs.cs
- XmlSchemaSequence.cs
- GPRECT.cs
- CaseInsensitiveOrdinalStringComparer.cs
- ProjectedSlot.cs
- NetworkInformationPermission.cs
- ConnectionPoint.cs
- ApplicationFileCodeDomTreeGenerator.cs
- webclient.cs
- RootBuilder.cs
- SynchronizedInputHelper.cs
- ParallelQuery.cs
- PaperSource.cs
- DummyDataSource.cs
- SslStream.cs
- DiagnosticTraceSource.cs
- NoResizeSelectionBorderGlyph.cs
- CommandValueSerializer.cs
- RequestDescription.cs
- Queue.cs
- PhysicalAddress.cs
- TypeSemantics.cs
- ImageFormatConverter.cs
- CustomAttributeBuilder.cs
- ToolStripButton.cs
- KnownTypes.cs
- TextSelectionHighlightLayer.cs
- Light.cs
- ToolboxItem.cs
- WindowsRegion.cs
- SoapSchemaExporter.cs
- TaskFormBase.cs
- FramingEncoders.cs
- HtmlTableCellCollection.cs
- ACE.cs
- ClonableStack.cs