protected override Expression VisitBinary()

in src/Epam.GraphQL/Helpers/ConditionExpressionRewriter.cs [110:235]


            protected override Expression VisitBinary(BinaryExpression node)
            {
                // If only right parameter depepends on parameter for rewriting...
                if (!node.Left.ContainsParameter(_dependendParam) && node.Right.ContainsParameter(_dependendParam))
                {
                    var rightNode = VisitExpr(node.Right, _dependendParam, _independendParam, _items);

                    // (e, d) => e.Id == d.Id
                    // (e, d) => 1 == d.Id
                    if (node.NodeType == ExpressionType.Equal)
                    {
                        // (e, d) => e.Id == d.Id    ------------->    items.Select(d => d.Id).Contains(e.Id)
                        // (e, d) => 1 == d.Id       ------------->    items.Select(d => d.Id).Contains(1)
                        return MakeContainsExpression(node.Left, rightNode, _items);
                    }

                    if (node.NodeType == ExpressionType.NotEqual)
                    {
                        return Expression.Not(MakeContainsExpression(node.Left, rightNode, _items));
                    }

                    if (IsLogicalExpression(node))
                    {
                        return Expression.MakeBinary(node.NodeType, node.Left, rightNode);
                    }

                    throw new NotSupportedException();
                }

                // If only left parameter depepends on parameter for rewriting...
                if (node.Left.ContainsParameter(_dependendParam) && !node.Right.ContainsParameter(_dependendParam))
                {
                    var leftNode = VisitExpr(node.Left, _dependendParam, _independendParam, _items);

                    if (node.NodeType == ExpressionType.Equal)
                    {
                        return MakeContainsExpression(node.Right, leftNode, _items);
                    }

                    if (node.NodeType == ExpressionType.NotEqual)
                    {
                        return Expression.Not(MakeContainsExpression(node.Right, leftNode, _items));
                    }

                    if (IsLogicalExpression(node))
                    {
                        return Expression.MakeBinary(node.NodeType, leftNode, node.Right);
                    }

                    throw new NotSupportedException();
                }

                // If both parameters depepends on parameter for rewriting...
                if (node.Left.ContainsParameter(_dependendParam) && node.Right.ContainsParameter(_dependendParam))
                {
                    // (e, d) => e.Id == d.Id && d.Id == 1
                    // (e, d) => d.Id == 1 && e.Id == d.Id
                    // (e, d) => e.Id == d.Id && e.AnotherId == d.AnotherId
                    // (e, d) => e.Id == d.Id || d.Id == 1
                    if (IsLogicalExpression(node))
                    {
                        // (e, d) => e.Id == d.Id && d.Id == 1
                        // (e, d) => e.Id == d.Id || d.Id == 1
                        if (node.Left.ContainsParameter(_independendParam))
                        {
                            // (e, d) => d.Id == 1 && d.Id == 1
                            if (node.NodeType is ExpressionType.And or ExpressionType.AndAlso)
                            {
                                return VisitExpr(
                                    node.Left,
                                    _dependendParam,
                                    _independendParam,
                                    MakeWhereExpression(_items, node.Right));
                            }

                            // (e, d) => d.Id == 1 || d.Id == 1
                            return Expression.MakeBinary(
                                node.NodeType,
                                VisitExpr(node.Left, _dependendParam, _independendParam, _items),
                                MakeAnyExpression(MakeWhereExpression(_items, node.Right)));
                        }

                        // (e, d) => d.Id == 1 && e.Id == d.Id
                        // (e, d) => d.Id == 1 || e.Id == d.Id
                        if (node.Right.ContainsParameter(_independendParam))
                        {
                            // (e, d) => d.Id == 1 && e.Id == d.Id
                            if (node.NodeType is ExpressionType.And or ExpressionType.AndAlso)
                            {
                                return VisitExpr(
                                    node.Right,
                                    _dependendParam,
                                    _independendParam,
                                    MakeWhereExpression(_items, node.Left));
                            }

                            // (e, d) => d.Id == 1 || e.Id == d.Id
                            return Expression.MakeBinary(
                                node.NodeType,
                                MakeAnyExpression(MakeWhereExpression(_items, node.Left)),
                                VisitExpr(node.Right, _dependendParam, _independendParam, _items));
                        }

                        // (e, d) => e.Id == d.Id && e.AnotherId == d.AnotherId
                        if (node.Left.ContainsParameter(_independendParam) && node.Right.ContainsParameter(_independendParam))
                        {
                            return Expression.MakeBinary(
                                node.NodeType,
                                VisitExpr(node.Left, _dependendParam, _independendParam, _items),
                                VisitExpr(node.Right, _dependendParam, _independendParam, _items));
                        }

                        // (e, d) => d.Id == 1 && d.Id == 1
                        // (e, d) => d.Id == 1 || d.Id == 1
                        return Expression.MakeBinary(
                            node.NodeType,
                            MakeAnyExpression(MakeWhereExpression(_items, node.Left)),
                            MakeAnyExpression(MakeWhereExpression(_items, node.Right)));
                    }

                    throw new NotSupportedException();
                }

                // Expression does not depend on parameter for rewriting...
                return node;
            }