< Summary

Class:Azure.Data.Tables.Queryable.Evaluator
Assembly:Azure.Data.Tables
File(s):C:\Git\azure-sdk-for-net\sdk\tables\Azure.Data.Tables\src\Queryable\Evaluator.cs
Covered lines:41
Uncovered lines:0
Coverable lines:41
Total lines:131
Line coverage:100% (41 of 41)
Covered branches:22
Total branches:22
Branch coverage:100% (22 of 22)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
PartialEval(...)-100%100%
PartialEval(...)-100%100%
CanBeEvaluatedLocally(...)-100%100%
.ctor(...)-100%100%
Eval(...)-100%100%
Visit(...)-100%100%
Evaluate(...)-100%100%
.ctor(...)-100%100%
Nominate(...)-100%100%
Visit(...)-100%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\tables\Azure.Data.Tables\src\Queryable\Evaluator.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Diagnostics;
 7using System.Linq.Expressions;
 8
 9namespace Azure.Data.Tables.Queryable
 10{
 11    internal static class Evaluator
 12    {
 13        internal static Expression PartialEval(Expression expression, Func<Expression, bool> canBeEvaluated)
 14        {
 46015            Nominator nominator = new Nominator(canBeEvaluated);
 46016            HashSet<Expression> candidates = nominator.Nominate(expression);
 46017            return new SubtreeEvaluator(candidates).Eval(expression);
 18        }
 19
 20        internal static Expression PartialEval(Expression expression)
 21        {
 46022            return PartialEval(expression, Evaluator.CanBeEvaluatedLocally);
 23        }
 24
 25        private static bool CanBeEvaluatedLocally(Expression expression)
 26        {
 289827            return expression.NodeType != ExpressionType.Parameter &&
 289828                expression.NodeType != ExpressionType.Lambda
 289829                && expression.NodeType != (ExpressionType)ResourceExpressionType.RootResourceSet;
 30        }
 31
 32        internal class SubtreeEvaluator : LinqExpressionVisitor
 33        {
 34            private HashSet<Expression> candidates;
 35
 46036            internal SubtreeEvaluator(HashSet<Expression> candidates)
 37            {
 46038                this.candidates = candidates;
 46039            }
 40
 41            internal Expression Eval(Expression exp)
 42            {
 46043                return Visit(exp);
 44            }
 45
 46            internal override Expression Visit(Expression exp)
 47            {
 555448                if (exp == null)
 49                {
 114850                    return null;
 51                }
 52
 440653                if (candidates.Contains(exp))
 54                {
 108455                    return Evaluate(exp);
 56                }
 57
 332258                return base.Visit(exp);
 59            }
 60
 61            private static Expression Evaluate(Expression e)
 62            {
 108463                if (e.NodeType == ExpressionType.Constant)
 64                {
 62665                    return e;
 66                }
 67
 45868                LambdaExpression lambda = Expression.Lambda(e);
 45869                Delegate fn = lambda.Compile();
 45870                object constantValue = fn.DynamicInvoke(null);
 71                Debug.Assert(!(constantValue is Expression), "!(constantValue is Expression)");
 72
 45873                Type constantType = e.Type;
 45874                if (constantValue != null && constantType.IsArray && constantType.GetElementType() == constantValue.GetT
 75                {
 3676                    constantType = constantValue.GetType();
 77                }
 78
 45879                return Expression.Constant(constantValue, constantType);
 80            }
 81        }
 82
 83        internal class Nominator : LinqExpressionVisitor
 84        {
 85            private Func<Expression, bool> functionCanBeEvaluated;
 86
 87            private HashSet<Expression> candidates;
 88
 89            private bool cannotBeEvaluated;
 90
 46091            internal Nominator(Func<Expression, bool> functionCanBeEvaluated)
 92            {
 46093                this.functionCanBeEvaluated = functionCanBeEvaluated;
 46094            }
 95
 96            internal HashSet<Expression> Nominate(Expression expression)
 97            {
 46098                candidates = new HashSet<Expression>(EqualityComparer<Expression>.Default);
 46099                Visit(expression);
 460100                return candidates;
 101            }
 102
 103            internal override Expression Visit(Expression expression)
 104            {
 6580105                if (expression != null)
 106                {
 5412107                    bool saveCannotBeEvaluated = cannotBeEvaluated;
 5412108                    cannotBeEvaluated = false;
 109
 5412110                    base.Visit(expression);
 111
 5412112                    if (!cannotBeEvaluated)
 113                    {
 2898114                        if (functionCanBeEvaluated(expression))
 115                        {
 2090116                            candidates.Add(expression);
 117                        }
 118                        else
 119                        {
 808120                            cannotBeEvaluated = true;
 121                        }
 122                    }
 123
 5412124                    cannotBeEvaluated |= saveCannotBeEvaluated;
 125                }
 126
 6580127                return expression;
 128            }
 129        }
 130    }
 131}