BoolExpressionVisitors.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / BoolExpressionVisitors.cs / 1305376 / BoolExpressionVisitors.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

 
using System.Data.Common.Utils;
using System.Data.Common.Utils.Boolean;
using System.Text;
using System.Collections.Generic; 
using System.Diagnostics;
using System.Data.Entity; 
 
namespace System.Data.Mapping.ViewGeneration.Structures
{ 

    using BoolDomainConstraint = DomainConstraint;

    using DomainBoolExpr = BoolExpr>; 
    using DomainTreeExpr = TreeExpr>;
    using DomainNotExpr = NotExpr>; 
    using DomainAndExpr = AndExpr>; 
    using DomainOrExpr = OrExpr>;
    using DomainTermExpr = TermExpr>; 
    using DomainTrueExpr = TrueExpr>;
    using DomainFalseExpr = FalseExpr>;

    // This class represents an arbitrary boolean expression 
    internal partial class BoolExpression : InternalBase
    { 
 
        #region FixRangeVisitor
        // A visitor that "fixes" the OneOfConsts according to the value of 
        // the Range in the DomainConstraint
        private class FixRangeVisitor : BasicVisitor
        {
 
            #region Constructor/Fields/Invocation
            private FixRangeVisitor(MemberDomainMap memberDomainMap) 
            { 
                m_memberDomainMap = memberDomainMap;
            } 

            private MemberDomainMap m_memberDomainMap;

            // effects: Given expression and the domains of various members, 
            // ensures that the range in OneOfConsts is in line with the
            // DomainConstraints in expression 
            internal static DomainBoolExpr FixRange(DomainBoolExpr expression, MemberDomainMap memberDomainMap) 
            {
                FixRangeVisitor visitor = new FixRangeVisitor(memberDomainMap); 
                DomainBoolExpr result = expression.Accept(visitor);
                return result;
            }
            #endregion 

            #region Visitors 
            // The real work happens here in the literal's FixRange 
            internal override DomainBoolExpr VisitTerm(DomainTermExpr expression)
            { 
                BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
                DomainBoolExpr result = literal.FixRange(expression.Identifier.Range, m_memberDomainMap);
                return result;
            } 
            #endregion
        } 
        #endregion 

        #region IsFinalVisitor 
        // A Visitor that determines if the OneOfConsts in this are fully
        // done or not
        private class IsFinalVisitor : Visitor
        { 

            internal static bool IsFinal(DomainBoolExpr expression) 
            { 
                IsFinalVisitor visitor = new IsFinalVisitor();
                return expression.Accept(visitor); 
            }

            #region Visitors
            internal override bool VisitTrue(DomainTrueExpr expression) 
            {
                return true; 
            } 

            internal override bool VisitFalse(DomainFalseExpr expression) 
            {
                return true;
            }
 
            // Check if the oneOfConst is fully done or not
            internal override bool VisitTerm(DomainTermExpr expression) 
            { 
                BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
                MemberRestriction restriction = literal as MemberRestriction; 
                bool result = restriction == null || restriction.IsFullyDone == true;
                return result;
            }
 
            internal override bool VisitNot(DomainNotExpr expression)
            { 
                return expression.Child.Accept(this); 
            }
 
            internal override bool VisitAnd(DomainAndExpr expression)
            {
                return VisitAndOr(expression);
            } 

            internal override bool VisitOr(DomainOrExpr expression) 
            { 
                return VisitAndOr(expression);
            } 

            private bool VisitAndOr(DomainTreeExpr expression)
            {
                // If any child is not final, tree is not final -- we cannot 
                // have a mix of final and non-final trees!
                bool isFirst = true; 
                bool result = true; 
                foreach (DomainBoolExpr child in expression.Children)
                { 
                    if (child as DomainFalseExpr != null || child as DomainTrueExpr != null)
                    {
                        // Ignore true or false since they carry no information
                        continue; 
                    }
                    bool isChildFinal = child.Accept(this); 
                    if (isFirst) 
                    {
                        result = isChildFinal; 
                    }
                    Debug.Assert(result == isChildFinal, "All children must be final or non-final");
                    isFirst = false;
                } 
                return result;
            } 
            #endregion 
        }
        #endregion 

        #region RemapBoolVisitor
        // A visitor that remaps the JoinTreeNodes in a bool tree
        private class RemapBoolVisitor : BasicVisitor 
        {
 
            #region Constructor/Fields/Invocation 
            // effects: Creates a visitor with the JoinTreeNode remapping
            // information in remap 
            private RemapBoolVisitor(MemberDomainMap memberDomainMap, Dictionary remap)
            {
                m_remap = remap;
                m_memberDomainMap = memberDomainMap; 
            }
 
            private Dictionary m_remap; 
            private MemberDomainMap m_memberDomainMap;
 
            internal static DomainBoolExpr RemapExtentTreeNodes(DomainBoolExpr expression, MemberDomainMap memberDomainMap,
                                                              Dictionary remap)
            {
                RemapBoolVisitor visitor = new RemapBoolVisitor(memberDomainMap, remap); 
                DomainBoolExpr result = expression.Accept(visitor);
                return result; 
            } 
            #endregion
 
            #region Visitors
            // The real work happens here in the literal's RemapBool
            internal override DomainBoolExpr VisitTerm(DomainTermExpr expression)
            { 
                BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
                BoolLiteral newLiteral = literal.RemapBool(m_remap); 
                return newLiteral.GetDomainBoolExpression(m_memberDomainMap); 
            }
            #endregion 
        }
        #endregion

 
        #region RequiredSlotsVisitor
        // A visitor that determines the slots required in the whole tree (for 
        // CQL Generation) 
        private class RequiredSlotsVisitor : BasicVisitor
        { 

            #region Constructor/Fields/Invocation
            private RequiredSlotsVisitor(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots)
            { 
                m_projectedSlotMap = projectedSlotMap;
                m_requiredSlots = requiredSlots; 
            } 

            private MemberProjectionIndex m_projectedSlotMap; 
            private bool[] m_requiredSlots;

            internal static void GetRequiredSlots(DomainBoolExpr expression, MemberProjectionIndex projectedSlotMap,
                                                  bool[] requiredSlots) 
            {
                RequiredSlotsVisitor visitor = new RequiredSlotsVisitor(projectedSlotMap, requiredSlots); 
                expression.Accept(visitor); 
            }
            #endregion 

            #region Visitors
            // The real work happends here - the slots are obtained from the literal
            internal override DomainBoolExpr VisitTerm(DomainTermExpr expression) 
            {
                BoolLiteral literal = BoolExpression.GetBoolLiteral(expression); 
                literal.GetRequiredSlots(m_projectedSlotMap, m_requiredSlots); 
                return expression;
            } 
            #endregion
        }
        #endregion
 
        // A Visitor that determines the CQL format of this expression
        #region AsCqlVisitor 
        private class AsCqlVisitor : Visitor 
        {
 
            #region Constructor/Fields/Invocation
            private AsCqlVisitor(StringBuilder builder, string blockAlias)
            {
                m_builder = builder; 
                m_blockAlias = blockAlias;
                // All boolean expressions can evaluate to true or not true 
                // (i.e., false or unknown) whether it is in CASE statements 
                // or WHERE clauses
                m_canSkipIsNotNull = true; 
            }

            private StringBuilder m_builder;
            private string m_blockAlias; 
            // We could maintain a stack of bools ratehr than a single
            // boolean for the visitor to allow IS NOT NULLs to be not 
            // generated for some scenarios 
            private bool m_canSkipIsNotNull;
 
            internal static StringBuilder AsCql(DomainBoolExpr expression, StringBuilder builder, string blockAlias)
            {
                AsCqlVisitor visitor = new AsCqlVisitor(builder, blockAlias);
                return expression.Accept(visitor); 
            }
            #endregion 
 
            #region Visitors
            internal override StringBuilder VisitTrue(DomainTrueExpr expression) 
            {
                m_builder.Append("True");
                return m_builder;
            } 

            internal override StringBuilder VisitFalse(DomainFalseExpr expression) 
            { 
                m_builder.Append("False");
                return m_builder; 
            }

            internal override StringBuilder VisitTerm(DomainTermExpr expression)
            { 
                // If m_canSkipIsNotNull is true at this point, it means that no ancestor of this
                // node is OR or NOT 
                BoolLiteral literal = BoolExpression.GetBoolLiteral(expression); 
                return literal.AsCql(m_builder, m_blockAlias, m_canSkipIsNotNull);
            } 

            internal override StringBuilder VisitNot(DomainNotExpr expression)
            {
                m_canSkipIsNotNull = false; // Cannot skip in NOTs 
                m_builder.Append("NOT(");
                // We do not need the returned StringBuilder -- it is the same as m_builder 
                expression.Child.Accept(this); 
                m_builder.Append(")");
                return m_builder; 
            }

            internal override StringBuilder VisitAnd(DomainAndExpr expression)
            { 
                return VisitAndOr(expression, ExprType.And);
            } 
 
            internal override StringBuilder VisitOr(DomainOrExpr expression)
            { 
                return VisitAndOr(expression, ExprType.Or);
            }

            private StringBuilder VisitAndOr(DomainTreeExpr expression, ExprType kind) 
            {
                Debug.Assert(kind == ExprType.Or || kind == ExprType.And); 
 
                m_builder.Append('(');
                bool isFirstChild = true; 
                foreach (DomainBoolExpr child in expression.Children)
                {
                    if (false == isFirstChild)
                    { 
                        // Add the operator
                        if (kind == ExprType.And) 
                        { 
                            m_builder.Append(" AND ");
                        } 
                        else
                        {
                            m_builder.Append(" OR ");
                        } 
                    }
                    isFirstChild = false; 
                    // Recursively get the CQL for the child 
                    child.Accept(this);
                } 
                m_builder.Append(')');
                return m_builder;
            }
            #endregion 
        }
        #endregion 
 
        // A Visitor that produces User understandable string of the given configuration represented by the BooleanExpression
        #region AsUserStringVisitor 
        private class AsUserStringVisitor : Visitor
        {

            #region Constructor/Fields/Invocation 
            private AsUserStringVisitor(StringBuilder builder, string blockAlias)
            { 
                m_builder = builder; 
                m_blockAlias = blockAlias;
                // All boolean expressions can evaluate to true or not true 
                // (i.e., false or unknown) whether it is in CASE statements
                // or WHERE clauses
                m_canSkipIsNotNull = true;
            } 

            private StringBuilder m_builder; 
            private string m_blockAlias; 
            // We could maintain a stack of bools ratehr than a single
            // boolean for the visitor to allow IS NOT NULLs to be not 
            // generated for some scenarios
            private bool m_canSkipIsNotNull;

            internal static StringBuilder AsUserString(DomainBoolExpr expression, StringBuilder builder, string blockAlias) 
            {
                AsUserStringVisitor visitor = new AsUserStringVisitor(builder, blockAlias); 
                return expression.Accept(visitor); 
            }
            #endregion 

            #region Visitors
            internal override StringBuilder VisitTrue(DomainTrueExpr expression)
            { 
                m_builder.Append("True");
                return m_builder; 
            } 

            internal override StringBuilder VisitFalse(DomainFalseExpr expression) 
            {
                m_builder.Append("False");
                return m_builder;
            } 

            internal override StringBuilder VisitTerm(DomainTermExpr expression) 
            { 
                // If m_canSkipIsNotNull is true at this point, it means that no ancestor of this
                // node is OR or NOT 

                BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);

                if (literal is ScalarRestriction || literal is TypeRestriction) 
                {
                    return literal.AsUserString(m_builder, Strings.ViewGen_EntityInstanceToken, m_canSkipIsNotNull); 
                } 

                return literal.AsUserString(m_builder, m_blockAlias, m_canSkipIsNotNull); 
            }

            internal override StringBuilder VisitNot(DomainNotExpr expression)
            { 
                m_canSkipIsNotNull = false; // Cannot skip in NOTs
 
                DomainTermExpr termExpr = expression.Child as DomainTermExpr; 
                if (termExpr != null)
                { 
                    BoolLiteral literal = BoolExpression.GetBoolLiteral(termExpr);
                    return literal.AsNegatedUserString(m_builder, m_blockAlias, m_canSkipIsNotNull);
                }
                else 
                {
                    m_builder.Append("NOT("); 
                    // We do not need the returned StringBuilder -- it is the same as m_builder 
                    expression.Child.Accept(this);
                    m_builder.Append(")"); 
                }
                return m_builder;
            }
 
            internal override StringBuilder VisitAnd(DomainAndExpr expression)
            { 
                return VisitAndOr(expression, ExprType.And); 
            }
 
            internal override StringBuilder VisitOr(DomainOrExpr expression)
            {
                return VisitAndOr(expression, ExprType.Or);
            } 

            private StringBuilder VisitAndOr(DomainTreeExpr expression, ExprType kind) 
            { 
                Debug.Assert(kind == ExprType.Or || kind == ExprType.And);
 
                m_builder.Append('(');
                bool isFirstChild = true;
                foreach (DomainBoolExpr child in expression.Children)
                { 
                    if (false == isFirstChild)
                    { 
                        // Add the operator 
                        if (kind == ExprType.And)
                        { 
                            m_builder.Append(" AND ");
                        }
                        else
                        { 
                            m_builder.Append(" OR ");
                        } 
                    } 
                    isFirstChild = false;
                    // Recursively get the CQL for the child 
                    child.Accept(this);
                }
                m_builder.Append(')');
                return m_builder; 
            }
            #endregion 
        } 
        #endregion
 

        // Given an expression that has no NOTs or ORs (if allowAllOperators
        // is false in GetTerms), generates the terms  in it
        #region TermVisitor 
        private class TermVisitor : Visitor>
        { 
            #region Constructor/Fields/Invocation 
            private TermVisitor(bool allowAllOperators)
            { 
                m_allowAllOperators = allowAllOperators;
            }

            // effectS: Returns all the terms in expression. If 
            // allowAllOperators is true, ensures that there are no NOTs or ORs
            internal static IEnumerable GetTerms(DomainBoolExpr expression, bool allowAllOperators) 
            { 
                TermVisitor visitor = new TermVisitor(allowAllOperators);
                return expression.Accept>(visitor); 
            }
            #endregion

            #region Fields 
            private bool m_allowAllOperators;
            #endregion 
 
            #region Visitors
            internal override IEnumerable VisitTrue(DomainTrueExpr expression) 
            {
                yield break; // No Atoms here -- we are not looking for constants
            }
 
            internal override IEnumerable VisitFalse(DomainFalseExpr expression)
            { 
                yield break; // No Atoms here -- we are not looking for constants 
            }
 
            internal override IEnumerable VisitTerm(DomainTermExpr expression)
            {
                yield return expression;
            } 

            internal override IEnumerable VisitNot(DomainNotExpr expression) 
            { 
                Debug.Assert(m_allowAllOperators, "Term should not be called when Nots are present in the expression");
                return VisitTreeNode(expression); 
            }

            private IEnumerable VisitTreeNode(DomainTreeExpr expression)
            { 
                foreach (DomainBoolExpr child in expression.Children)
                { 
                    foreach (DomainTermExpr result in child.Accept(this)) 
                    {
                        yield return result; 
                    }
                }
            }
 
            internal override IEnumerable VisitAnd(DomainAndExpr expression)
            { 
                return VisitTreeNode(expression); 
            }
 
            internal override IEnumerable VisitOr(DomainOrExpr expression)
            {
                Debug.Assert(m_allowAllOperators, "TermVisitor should not be called when Ors are present in the expression");
                return VisitTreeNode(expression); 
            }
            #endregion 
        } 
        #endregion
 
        #region CompactStringVisitor
        // Generates a human readable version of the expression and places it in
        // the StringBuilder
        private class CompactStringVisitor : Visitor 
        {
 
            #region Constructor/Fields/Invocation 
            private CompactStringVisitor(StringBuilder builder)
            { 
                m_builder = builder;
            }

 
            private StringBuilder m_builder;
 
            internal static StringBuilder ToBuilder(DomainBoolExpr expression, StringBuilder builder) 
            {
                CompactStringVisitor visitor = new CompactStringVisitor(builder); 
                return expression.Accept(visitor);
            }
            #endregion
 
            #region Visitors
            internal override StringBuilder VisitTrue(DomainTrueExpr expression) 
            { 
                m_builder.Append("True");
                return m_builder; 
            }

            internal override StringBuilder VisitFalse(DomainFalseExpr expression)
            { 
                m_builder.Append("False");
                return m_builder; 
            } 

            internal override StringBuilder VisitTerm(DomainTermExpr expression) 
            {
                BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
                literal.ToCompactString(m_builder);
                return m_builder; 
            }
 
            internal override StringBuilder VisitNot(DomainNotExpr expression) 
            {
                m_builder.Append("NOT("); 
                expression.Child.Accept(this);
                m_builder.Append(")");
                return m_builder;
            } 

            internal override StringBuilder VisitAnd(DomainAndExpr expression) 
            { 
                return VisitAndOr(expression, "AND");
            } 

            internal override StringBuilder VisitOr(DomainOrExpr expression)
            {
                return VisitAndOr(expression, "OR"); 
            }
 
            private StringBuilder VisitAndOr(DomainTreeExpr expression, string opAsString) 
            {
                List childrenStrings = new List(); 
                StringBuilder builder = m_builder;
                // Save the old string builder and pass a new one to each child
                foreach (DomainBoolExpr child in expression.Children)
                { 
                    m_builder = new StringBuilder();
                    child.Accept(this); 
                    childrenStrings.Add(m_builder.ToString()); 
                }
                // Now store the children in a sorted manner 
                m_builder = builder;
                m_builder.Append('(');
                StringUtil.ToSeparatedStringSorted(m_builder, childrenStrings, " " + opAsString + " ");
                m_builder.Append(')'); 
                return m_builder;
            } 
            #endregion 
        }
        #endregion 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK