Beispiel #1
0
        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);
        }
Beispiel #2
0
        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");
            }
        }