protected Term SimpleMap(IDatumConverterFactory datumConverterFactory, Expression expr) { switch (expr.NodeType) { case ExpressionType.Constant: { var constantExpression = (ConstantExpression)expr; var datumConverter = datumConverterFactory.Get(constantExpression.Type); var datum = datumConverter.ConvertObject(constantExpression.Value); return(new Term() { type = Term.TermType.DATUM, datum = datum }); } case ExpressionType.Add: case ExpressionType.Modulo: case ExpressionType.Divide: case ExpressionType.Multiply: case ExpressionType.Subtract: case ExpressionType.Equal: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.AndAlso: case ExpressionType.OrElse: case ExpressionType.NotEqual: case ExpressionType.ArrayIndex: return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, datumConverterFactory)); case ExpressionType.Not: case ExpressionType.ArrayLength: return(ConvertUnaryExpressionToTerm((UnaryExpression)expr, datumConverterFactory)); case ExpressionType.New: { var newExpression = (NewExpression)expr; if (AnonymousTypeDatumConverterFactory.Instance.IsTypeSupported(newExpression.Type)) { var retval = new Term() { type = Term.TermType.MAKE_OBJ, }; foreach (var property in newExpression.Type.GetProperties().Select((p, i) => new { Property = p, Index = i })) { var key = property.Property.Name; var value = RecursiveMap(newExpression.Arguments[property.Index]); retval.optargs.Add(new Term.AssocPair() { key = key, val = value }); } return(retval); } DefaultExpressionConverterFactory.ExpressionMappingDelegate <NewExpression> newExpressionMapping; if (expressionConverterFactory.TryGetNewExpressionMapping(newExpression.Constructor, out newExpressionMapping)) { return(newExpressionMapping(newExpression, RecursiveMap, datumConverterFactory, expressionConverterFactory)); } return(AttemptClientSideConversion(datumConverterFactory, expr)); } case ExpressionType.Call: { var callExpression = (MethodCallExpression)expr; var method = callExpression.Method; DefaultExpressionConverterFactory.ExpressionMappingDelegate <MethodCallExpression> methodCallMapping; if (expressionConverterFactory.TryGetMethodCallMapping(method, out methodCallMapping)) { return(methodCallMapping(callExpression, RecursiveMap, datumConverterFactory, expressionConverterFactory)); } else { return(AttemptClientSideConversion(datumConverterFactory, expr)); } } case ExpressionType.MemberAccess: { var memberExpression = (MemberExpression)expr; var member = memberExpression.Member; DefaultExpressionConverterFactory.ExpressionMappingDelegate <MemberExpression> memberAccessMapping; if (expressionConverterFactory.TryGetMemberAccessMapping(member, out memberAccessMapping)) { return(memberAccessMapping(memberExpression, RecursiveMap, datumConverterFactory, expressionConverterFactory)); } else { return(AttemptClientSideConversion(datumConverterFactory, expr)); } } case ExpressionType.Conditional: { var conditionalExpression = (ConditionalExpression)expr; return(new Term() { type = Term.TermType.BRANCH, args = { RecursiveMap(conditionalExpression.Test), RecursiveMap(conditionalExpression.IfTrue), RecursiveMap(conditionalExpression.IfFalse) } }); } default: { return(AttemptClientSideConversion(datumConverterFactory, expr)); } } }
protected Term SimpleMap(IDatumConverterFactory datumConverterFactory, Expression expr) { switch (expr.NodeType) { case ExpressionType.Constant: { var constantExpression = (ConstantExpression)expr; var datumConverter = datumConverterFactory.Get(constantExpression.Type); var datum = datumConverter.ConvertObject(constantExpression.Value); return(new Term() { type = Term.TermType.DATUM, datum = datum }); } case ExpressionType.Add: case ExpressionType.Modulo: case ExpressionType.Divide: case ExpressionType.Multiply: case ExpressionType.Subtract: case ExpressionType.Equal: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.AndAlso: case ExpressionType.OrElse: case ExpressionType.NotEqual: case ExpressionType.ArrayIndex: return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, datumConverterFactory)); case ExpressionType.Not: case ExpressionType.ArrayLength: return(ConvertUnaryExpressionToTerm((UnaryExpression)expr, datumConverterFactory)); case ExpressionType.New: { var newExpression = (NewExpression)expr; if (AnonymousTypeDatumConverterFactory.Instance.IsTypeSupported(newExpression.Type)) { var retval = new Term() { type = Term.TermType.MAKE_OBJ, }; foreach (var property in newExpression.Type.GetProperties().Select((p, i) => new { Property = p, Index = i })) { var key = property.Property.Name; var value = RecursiveMap(newExpression.Arguments[property.Index]); retval.optargs.Add(new Term.AssocPair() { key = key, val = value }); } return(retval); } DefaultExpressionConverterFactory.ExpressionMappingDelegate <NewExpression> newExpressionMapping; if (expressionConverterFactory.TryGetNewExpressionMapping(newExpression.Constructor, out newExpressionMapping)) { return(newExpressionMapping(newExpression, RecursiveMap, datumConverterFactory, expressionConverterFactory)); } return(AttemptClientSideConversion(datumConverterFactory, expr)); } case ExpressionType.Call: { var callExpression = (MethodCallExpression)expr; var method = callExpression.Method; DefaultExpressionConverterFactory.ExpressionMappingDelegate <MethodCallExpression> methodCallMapping; if (expressionConverterFactory.TryGetMethodCallMapping(method, out methodCallMapping)) { return(methodCallMapping(callExpression, RecursiveMap, datumConverterFactory, expressionConverterFactory)); } else { return(AttemptClientSideConversion(datumConverterFactory, expr)); } } case ExpressionType.MemberAccess: { var memberExpression = (MemberExpression)expr; var member = memberExpression.Member; DefaultExpressionConverterFactory.ExpressionMappingDelegate <MemberExpression> memberAccessMapping; if (expressionConverterFactory.TryGetMemberAccessMapping(member, out memberAccessMapping)) { return(memberAccessMapping(memberExpression, RecursiveMap, datumConverterFactory, expressionConverterFactory)); } Term serverSideTerm; if (ServerSideMemberAccess(datumConverterFactory, memberExpression, out serverSideTerm)) { return(serverSideTerm); } return(AttemptClientSideConversion(datumConverterFactory, expr)); } case ExpressionType.Conditional: { var conditionalExpression = (ConditionalExpression)expr; return(new Term() { type = Term.TermType.BRANCH, args = { RecursiveMap(conditionalExpression.Test), RecursiveMap(conditionalExpression.IfTrue), RecursiveMap(conditionalExpression.IfFalse) } }); } case ExpressionType.Convert: { // The use-case for this right now is automatic boxing that occurs when setting a Dictionary<string,object>'s value // to a primitive. In that particular case, we don't actually need to generate any ReQL for the conversion, so we're // just ignoring the Convert and mapping the expression inside. Might need other behavior here in the future... return(RecursiveMap(((UnaryExpression)expr).Operand)); } default: { return(AttemptClientSideConversion(datumConverterFactory, expr)); } } }