Evaluator.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 / DataWeb / Client / System / Data / Services / Client / ALinq / Evaluator.cs / 1305376 / Evaluator.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Provides funcletization of expression tree prior to resource binding.
//  
// 
// @owner  [....]
//--------------------------------------------------------------------- 
namespace System.Data.Services.Client
{
    using System;
    using System.Collections.Generic; 
    using System.Diagnostics;
    using System.Linq.Expressions; 
 
#if ASTORIA_LIGHT   // Hashset not available
    /// workaround until silver light client is updated 
    internal class HashSet : Dictionary, IEnumerable where T : class
    {
        /// workaround until silver light client is updated
        public HashSet() { } 

        /// workaround until silver light client is updated 
        public HashSet(IEqualityComparer comparer) : base(comparer) { } 

        /// workaround until silver light client is updated 
        public HashSet(IEnumerable collection, IEqualityComparer comparer) : base(comparer)
        {
           this.UnionWith(collection);
        } 

        /// workaround until silver light client is updated 
        public bool Add(T value) { if (!base.ContainsKey(value)) { base.Add(value, value); return true; } return false; } 

        /// workaround until silver light client is updated 
        public bool Contains(T value) { return base.ContainsKey(value); }

        /// workaround until silver light client is updated
        new public bool Remove(T value) { return base.Remove(value); } 

        /// workaround until silver light client is updated 
        new public IEnumerator GetEnumerator() { return base.Keys.GetEnumerator(); } 

        /// Modifies the current HashSet object to contain all elements that are present in both itself and in the specified collection. 
        /// The collection to compare to the current HashSet object.
        public void UnionWith(IEnumerable other)
        {
            if (other == null) 
            {
                throw new ArgumentNullException("other"); 
            } 

            foreach (T local in other) 
            {
                ////this.AddIfNotPresent(local);
                this.Add(local);
            } 
        }
    } 
#endif 

    ///  
    /// performs funcletization on an expression tree
    /// 
    internal static class Evaluator
    { 
        /// 
        /// Performs evaluation and replacement of independent sub-trees 
        ///  
        /// The root of the expression tree.
        /// A function that decides whether a given expression node can be part of the local function. 
        /// A new tree with sub-trees evaluated and replaced.
        internal static Expression PartialEval(Expression expression, Func canBeEvaluated)
        {
            Nominator nominator = new Nominator(canBeEvaluated); 
            HashSet candidates = nominator.Nominate(expression);
            return new SubtreeEvaluator(candidates).Eval(expression); 
        } 

        ///  
        /// Performs evaluation and replacement of independent sub-trees
        /// 
        /// The root of the expression tree.
        /// A new tree with sub-trees evaluated and replaced. 
        internal static Expression PartialEval(Expression expression)
        { 
            return PartialEval(expression, Evaluator.CanBeEvaluatedLocally); 
        }
 
        /// 
        /// Evaluates if an expression can be evaluated locally.
        /// 
        /// the expression. 
        /// true/ false if can be evaluated locally
        private static bool CanBeEvaluatedLocally(Expression expression) 
        { 
            return expression.NodeType != ExpressionType.Parameter &&
                expression.NodeType != ExpressionType.Lambda && 
                expression.NodeType != (ExpressionType) ResourceExpressionType.RootResourceSet;
        }

        ///  
        /// Evaluates and replaces sub-trees when first candidate is reached (top-down)
        ///  
        internal class SubtreeEvaluator : DataServiceALinqExpressionVisitor 
        {
            /// list of candidates 
            private HashSet candidates;

            /// 
            /// constructs an expression evaluator with a list of candidates 
            /// 
            /// List of expressions to evaluate 
            internal SubtreeEvaluator(HashSet candidates) 
            {
                this.candidates = candidates; 
            }

            /// 
            /// Evaluates an expression sub-tree 
            /// 
            /// The expression to evaluate. 
            /// The evaluated expression. 
            internal Expression Eval(Expression exp)
            { 
                return this.Visit(exp);
            }

            ///  
            /// Visit method for visitor
            ///  
            /// the expression to visit 
            /// visited expression
            internal override Expression Visit(Expression exp) 
            {
                if (exp == null)
                {
                    return null; 
                }
 
                if (this.candidates.Contains(exp)) 
                {
                    return Evaluate(exp); 
                }

                return base.Visit(exp);
            } 

            ///  
            /// Evaluates expression 
            /// 
            /// the expression to evaluate 
            /// constant expression with return value of evaluation
            private static Expression Evaluate(Expression e)
            {
                if (e.NodeType == ExpressionType.Constant) 
                {
                    return e; 
                } 

#if ASTORIA_LIGHT 
                LambdaExpression lambda = ExpressionHelpers.CreateLambda(e, new ParameterExpression[0]);
#else
                LambdaExpression lambda = Expression.Lambda(e);
#endif 
                Delegate fn = lambda.Compile();
                object constantValue = fn.DynamicInvoke(null); 
                Debug.Assert(!(constantValue is Expression), "!(constantValue is Expression)"); 

                // Use the expression type unless it's an array type, 
                // where the actual type may be a vector array rather
                // than an array with a dynamic lower bound.
                Type constantType = e.Type;
                if (constantValue != null && constantType.IsArray && constantType.GetElementType() == constantValue.GetType().GetElementType()) 
                {
                    constantType = constantValue.GetType(); 
                } 

                return Expression.Constant(constantValue, constantType); 
            }
        }

        ///  
        /// Performs bottom-up analysis to determine which nodes can possibly
        /// be part of an evaluated sub-tree. 
        ///  
        internal class Nominator : DataServiceALinqExpressionVisitor
        { 
            /// func to determine whether expression can be evaluated
            private Func functionCanBeEvaluated;

            /// candidate expressions for evaluation 
            private HashSet candidates;
 
            /// flag for when sub tree cannot be evaluated 
            private bool cannotBeEvaluated;
 
            /// 
            /// Creates the Nominator based on the function passed.
            /// 
            ///  
            /// A Func speficying whether an expression can be evaluated or not.
            ///  
            /// visited expression 
            internal Nominator(Func functionCanBeEvaluated)
            { 
                this.functionCanBeEvaluated = functionCanBeEvaluated;
            }

            ///  
            /// Nominates an expression to see if it can be evaluated
            ///  
            ///  
            /// Expression to check
            ///  
            /// a list of expression sub trees that can be evaluated
            internal HashSet Nominate(Expression expression)
            {
                this.candidates = new HashSet(EqualityComparer.Default); 
                this.Visit(expression);
                return this.candidates; 
            } 

            ///  
            /// Visit method for walking expression tree bottom up.
            /// 
            /// 
            /// root expression to visit 
            /// 
            /// visited expression 
            internal override Expression Visit(Expression expression) 
            {
                if (expression != null) 
                {
                    bool saveCannotBeEvaluated = this.cannotBeEvaluated;
                    this.cannotBeEvaluated = false;
 
                    base.Visit(expression);
 
                    if (!this.cannotBeEvaluated) 
                    {
                        if (this.functionCanBeEvaluated(expression)) 
                        {
                            this.candidates.Add(expression);
                        }
                        else 
                        {
                            this.cannotBeEvaluated = true; 
                        } 
                    }
 
                    this.cannotBeEvaluated |= saveCannotBeEvaluated;
                }

                return expression; 
            }
        } 
    } 
}

// 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