public override Expression CreateExpression(object context) { //return null; //var literalRight = Right as LiteralExpression; //var valueRight = Right as ValueExpression; //var dimensionRight = Right as DimensionExpression; //var literalLeft = Left as LiteralExpression; //var valueLeft = Left as ValueExpression; //var dimensionLeft = Left as DimensionExpression; var leftExpression = Left == null ? null : Left.CreateExpression(new DimensionCreateExpressionParameter { QuoteUnknownIdentifiers = Right == null, Left = Left, Right = Right }); var rightExpression = Right == null ? null : Right.CreateExpression(new DimensionCreateExpressionParameter { QuoteUnknownIdentifiers = true, Left = Left, Right = Right }); var asLeftRange = leftExpression as NewArrayExpression; var asRightRange = rightExpression as NewArrayExpression; if (asLeftRange != null) { throw new BermudaExpressionGenerationException("Ranges are only supported on the right hand side"); } if (asRightRange == null && leftExpression != null && rightExpression != null && leftExpression.Type != rightExpression.Type) { var asLeftLiteral = leftExpression as ConstantExpression; Expression asLeftDimension = leftExpression; var asRightLiteral = rightExpression as ConstantExpression; Expression asRightDimension = rightExpression; //if (asLeftDimension == null) asLeftDimension = leftExpression as MethodCallExpression; //if (asRightDimension == null) asRightDimension = asRightDimension as MethodCallExpression; try { if (asLeftLiteral == null && asRightLiteral == null) { rightExpression = Expression.Convert(rightExpression, leftExpression.Type); } else if (asLeftDimension != null && asRightLiteral != null) { var targetType = leftExpression.Type; if (ReduceExpressionGeneration.IsCollectionType(targetType)) { targetType = ReduceExpressionGeneration.GetTypeOfEnumerable(targetType); } if (ReduceExpressionGeneration.IsTupleType(targetType)) { targetType = targetType.GetGenericArguments().Last(); } long num; if (targetType == typeof(long) && asRightLiteral.Value is string && !long.TryParse(asRightLiteral.Value as string, out num)) { var lookupKey = leftExpression.ToString().Split('.').LastOrDefault(); if (!string.IsNullOrWhiteSpace(lookupKey)) { num = GetLookup(lookupKey, asRightLiteral.Value as string); } } rightExpression = Expression.Constant(Convert.ChangeType(asRightLiteral.Value, targetType)); } else if (asLeftLiteral != null && asRightDimension != null) { var targetType = rightExpression.Type; if (ReduceExpressionGeneration.IsCollectionType(targetType)) { targetType = ReduceExpressionGeneration.GetTypeOfEnumerable(targetType); } if (!ReduceExpressionGeneration.IsTupleType(targetType)) { targetType = targetType.GetGenericArguments().Last(); } leftExpression = Expression.Constant(Convert.ChangeType(asLeftLiteral.Value, targetType)); } else if (asLeftLiteral != null && asRightLiteral != null) { leftExpression = Expression.Constant(Convert.ChangeType(asLeftLiteral.Value, rightExpression.Type)); } else { throw new BermudaExpressionGenerationException("Not supposed to happen"); } } catch (Exception ex) { if (ex is BermudaExpressionGenerationException) { throw ex; } //throw new BermudaExpressionGenerationException("Failed to convert: " + ex.Message); Root.AddWarning(ex.ToString()); return(null); } } //if (literalRight == null && valueRight == null) //{ // throw new Exception("The selector must specify an expression child or a literal child"); //} //object rightValue = literalRight != null ? (object)literalRight.Value : (object)valueRight.Value; //object leftValue = literalLeft != null ? (object)literalLeft.Value : (object)valueLeft.Value; var getExpression = (GetExpression)Root; Type elementType = Root.ElementType; var xParam = Expression.Parameter(elementType, "x"); //freeform strings inside the query switch (NodeType) { case SelectorTypes.Unspecified: { if (Parent is DimensionExpression) { return(rightExpression); } if (Right != null) { var name = Right.ToString(); var boolField = ReduceExpressionGeneration.GetField(elementType, name, false); if (boolField != null) { Expression boolFieldAccess = Expression.MakeMemberAccess(xParam, boolField); return(boolFieldAccess); } //var isTrue = Expression.Equal(boolFieldAccess, Expression.Constant(true)); } return(CreateUnspecifiedStringExpression(rightExpression, elementType, xParam)); } case SelectorTypes.Unknown: { if (leftExpression == null || rightExpression == null) { return(null); } switch (Modifier) { case ModifierTypes.Contains: return(CreateCollectionContainsExpression(rightExpression, xParam, leftExpression)); case ModifierTypes.In: return(CreateInExpression(rightExpression, xParam, leftExpression)); case ModifierTypes.Like: case ModifierTypes.Colon: if (leftExpression.Type == typeof(string)) { return(CreateStringFieldContainsExpression(leftExpression, rightExpression)); } else if (ReduceExpressionGeneration.IsCollectionType(leftExpression.Type)) { goto case ModifierTypes.Contains; } else { if (asRightRange != null) { goto case ModifierTypes.InRange; } else { goto case ModifierTypes.Equals; } } case ModifierTypes.InRange: return(CreateInRangeExpression(leftExpression, asRightRange)); case ModifierTypes.Equals: return(Expression.Equal(leftExpression, rightExpression)); case ModifierTypes.GreaterThan: if (asRightRange != null) { goto case ModifierTypes.InRange; } return(Expression.GreaterThan(leftExpression, rightExpression)); case ModifierTypes.LessThan: if (asRightRange != null) { goto case ModifierTypes.InRange; } return(Expression.LessThan(leftExpression, rightExpression)); case ModifierTypes.Add: return(Expression.Add(leftExpression, rightExpression)); case ModifierTypes.Subtract: return(Expression.Add(leftExpression, rightExpression)); case ModifierTypes.Multiply: return(Expression.Add(leftExpression, rightExpression)); case ModifierTypes.Divide: return(Expression.Add(leftExpression, rightExpression)); default: throw new BermudaExpressionGenerationException("Unsupported Operator " + Modifier + " for Operands " + leftExpression + " and " + rightExpression); } } } return(null); }
public override Expression CreateExpression(object context) { var param = context as DimensionCreateExpressionParameter; if (Child != null) { var result = Child.CreateExpression(context); if (IsNegated) { result = Expression.Negate(result); } if (IsNotted) { result = Expression.Not(result); } return(result); } if (!IsFunctionCall) { var elementType = Root.ElementType; var path = Source; var targetField = ReduceExpressionGeneration.GetField(elementType, path, false); if (targetField == null) { var asContext = context as DimensionCreateExpressionParameter; if (asContext != null) { long longResult = 0; double doubleResult = 0; if (long.TryParse(Source, out longResult)) { return(Expression.Constant(longResult)); } else if (double.TryParse(Source, out doubleResult)) { return(Expression.Constant(doubleResult)); } else if (!asContext.QuoteUnknownIdentifiers && !IsQuoted) { return(null); } Expression cons = Expression.Constant(Convert.ChangeType(Source, SourceType)); if (IsNegated) { cons = Expression.Negate(cons); } if (IsNotted) { cons = Expression.Not(cons); } return(cons); } return(null); } var xParam = Expression.Parameter(elementType, "x"); if (targetField.FieldType == typeof(string) || targetField.FieldType == typeof(bool)) { return(Expression.MakeMemberAccess(xParam, targetField)); } else if (targetField.FieldType == typeof(long) || targetField.FieldType == typeof(double) || targetField.FieldType == typeof(int) || targetField.FieldType == typeof(float) || targetField.FieldType == typeof(DateTime)) { Expression memberAccessExpr = Expression.MakeMemberAccess(xParam, targetField); //if (IsNegated) // memberAccessExpr = Expression.Negate(memberAccessExpr); return(memberAccessExpr); } else if (ReduceExpressionGeneration.IsCollectionType(targetField.FieldType)) { return(Expression.MakeMemberAccess(xParam, targetField)); } else { var res = Expression.MakeMemberAccess(xParam, targetField); return(res); //throw new NotImplementedException("Unsupported field Type: " + targetField.FieldType.Name); } } else { var elementType = Root.ElementType; var xParam = Expression.Parameter(elementType, "x"); var asDim = (param.Left ?? param.Right) as DimensionExpression; var functionCall = ReduceExpressionGeneration.MakeFunctionCallExpression(asDim, elementType, xParam); return(functionCall); //throw new NotImplementedException("Not supported functions in where logic"); } }