/* This class was copied from Mehfuz's LinqExtender project, which is available from github. * http://mehfuzh.github.com/LinqExtender/ */ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Linq.Expressions; namespace Marr.Data.QGen { /// /// Expression visitor /// public class ExpressionVisitor { /// /// Visits expression and delegates call to different to branch. /// /// /// protected virtual Expression Visit(Expression expression) { if (expression == null) return null; switch (expression.NodeType) { case ExpressionType.Lambda: return VisitLamda((LambdaExpression)expression); case ExpressionType.ArrayLength: case ExpressionType.Convert: case ExpressionType.ConvertChecked: case ExpressionType.Negate: case ExpressionType.UnaryPlus: case ExpressionType.NegateChecked: case ExpressionType.Not: case ExpressionType.Quote: case ExpressionType.TypeAs: return this.VisitUnary((UnaryExpression)expression); case ExpressionType.Add: case ExpressionType.AddChecked: case ExpressionType.And: case ExpressionType.AndAlso: case ExpressionType.ArrayIndex: case ExpressionType.Coalesce: case ExpressionType.Divide: case ExpressionType.Equal: case ExpressionType.ExclusiveOr: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.LeftShift: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.Modulo: case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: case ExpressionType.NotEqual: case ExpressionType.Or: case ExpressionType.OrElse: case ExpressionType.Power: case ExpressionType.RightShift: case ExpressionType.Subtract: case ExpressionType.SubtractChecked: return this.VisitBinary((BinaryExpression)expression); case ExpressionType.Call: return this.VisitMethodCall((MethodCallExpression)expression); case ExpressionType.Constant: return this.VisitConstant((ConstantExpression)expression); case ExpressionType.MemberAccess: return this.VisitMemberAccess((MemberExpression)expression); case ExpressionType.Parameter: return this.VisitParameter((ParameterExpression)expression); } throw new ArgumentOutOfRangeException("expression", expression.NodeType.ToString()); } /// /// Visits the constance expression. To be implemented by user. /// /// /// protected virtual Expression VisitConstant(ConstantExpression expression) { return expression; } /// /// Visits the memeber access expression. To be implemented by user. /// /// /// protected virtual Expression VisitMemberAccess(MemberExpression expression) { return expression; } /// /// Visits the method call expression. To be implemented by user. /// /// /// protected virtual Expression VisitMethodCall(MethodCallExpression expression) { throw new NotImplementedException(); } /// /// Visits the binary expression. /// /// /// protected virtual Expression VisitBinary(BinaryExpression expression) { this.Visit(expression.Left); this.Visit(expression.Right); return expression; } /// /// Visits the unary expression. /// /// /// protected virtual Expression VisitUnary(UnaryExpression expression) { this.Visit(expression.Operand); return expression; } /// /// Visits the lamda expression. /// /// /// protected virtual Expression VisitLamda(LambdaExpression lambdaExpression) { this.Visit(lambdaExpression.Body); return lambdaExpression; } private Expression VisitParameter(ParameterExpression expression) { return expression; } } }