BoolExpressionVisitors.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / BoolExpressionVisitors.cs / 1 / 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); 
                OneOfConst oneOfConst = literal as OneOfConst; 
                bool result = oneOfConst == null || oneOfConst.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 RemapJoinTreeNodes(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(MemberPathMapBase projectedSlotMap, bool[] requiredSlots) { 
                m_projectedSlotMap = projectedSlotMap; 
                m_requiredSlots = requiredSlots;
            } 

            private MemberPathMapBase m_projectedSlotMap;
            private bool[] m_requiredSlots;
 
            internal static void GetRequiredSlots(DomainBoolExpr expression, MemberPathMapBase 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 OneOfScalarConst || literal is OneOfTypeConst) 
                {
                    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.
//---------------------------------------------------------------------- 
// 
//      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); 
                OneOfConst oneOfConst = literal as OneOfConst; 
                bool result = oneOfConst == null || oneOfConst.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 RemapJoinTreeNodes(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(MemberPathMapBase projectedSlotMap, bool[] requiredSlots) { 
                m_projectedSlotMap = projectedSlotMap; 
                m_requiredSlots = requiredSlots;
            } 

            private MemberPathMapBase m_projectedSlotMap;
            private bool[] m_requiredSlots;
 
            internal static void GetRequiredSlots(DomainBoolExpr expression, MemberPathMapBase 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 OneOfScalarConst || literal is OneOfTypeConst) 
                {
                    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