1using System.Linq.Expressions;
 
    5internal abstract class ExpressionSwitch<TResult>
 
    8    protected virtual bool Simplified { 
get => 
true; }
 
   10    public IEnumerable<TResult> ApplyAll(IEnumerable<Expression> exprs) =>
 
   11        exprs.Select(e => Apply(e));
 
   14    public TResult Apply(Expression? expr)
 
   16        if (expr is 
null) 
return NullExpr();
 
   18        return expr.NodeType 
switch 
   21            ExpressionType.AddAssign or
 
   22            ExpressionType.AddAssignChecked or
 
   23            ExpressionType.AddChecked or
 
   25            ExpressionType.AndAssign or
 
   26            ExpressionType.AndAlso or
 
   27            ExpressionType.ArrayIndex or
 
   28            ExpressionType.Assign or
 
   29            ExpressionType.Coalesce or
 
   30            ExpressionType.Divide or
 
   31            ExpressionType.DivideAssign or
 
   32            ExpressionType.Equal or
 
   33            ExpressionType.ExclusiveOr or
 
   34            ExpressionType.ExclusiveOrAssign or
 
   35            ExpressionType.GreaterThan or
 
   36            ExpressionType.GreaterThanOrEqual or
 
   37            ExpressionType.LeftShift or
 
   38            ExpressionType.LeftShiftAssign or
 
   39            ExpressionType.LessThan or
 
   40            ExpressionType.LessThanOrEqual or
 
   41            ExpressionType.Modulo or
 
   42            ExpressionType.ModuloAssign or
 
   43            ExpressionType.Multiply or
 
   44            ExpressionType.MultiplyAssign or
 
   45            ExpressionType.MultiplyAssignChecked or
 
   46            ExpressionType.MultiplyChecked or
 
   47            ExpressionType.NotEqual or
 
   49            ExpressionType.OrAssign or
 
   50            ExpressionType.OrElse or
 
   51            ExpressionType.Power or
 
   52            ExpressionType.PowerAssign or
 
   53            ExpressionType.RightShift or
 
   54            ExpressionType.RightShiftAssign or
 
   55            ExpressionType.Subtract or
 
   56            ExpressionType.SubtractAssign or
 
   57            ExpressionType.SubtractAssignChecked or
 
   58            ExpressionType.SubtractChecked =>
 
   59                BinaryExpr((BinaryExpression)expr),
 
   61            ExpressionType.Block =>
 
   62                BlockExpr((BlockExpression)expr),
 
   63            ExpressionType.Call =>
 
   64                CallExpr((MethodCallExpression)expr),
 
   65            ExpressionType.Conditional =>
 
   66                ConditionalExpr((ConditionalExpression)expr),
 
   67            ExpressionType.Constant =>
 
   68                ConstantExpr((ConstantExpression)expr),
 
   69            ExpressionType.DebugInfo =>
 
   70                DebugInfoExpr((DebugInfoExpression)expr),
 
   71            ExpressionType.Default =>
 
   72                DefaultExpr((DefaultExpression)expr),
 
   73            ExpressionType.Dynamic =>
 
   74                DynamicExpr((DynamicExpression)expr),
 
   75            ExpressionType.Goto =>
 
   76                GotoExpr((GotoExpression)expr),
 
   77            ExpressionType.Index =>
 
   78                IndexExpr((IndexExpression)expr),
 
   79            ExpressionType.Invoke =>
 
   80                InvokeExpr((InvocationExpression)expr),
 
   81            ExpressionType.Label =>
 
   82                LabelExpr((LabelExpression)expr),
 
   83            ExpressionType.Lambda =>
 
   84                LambdaExpr((LambdaExpression)expr),
 
   85            ExpressionType.Loop =>
 
   86                LoopExpr((LoopExpression)expr),
 
   87            ExpressionType.ListInit =>
 
   88                ListInitExpr((ListInitExpression)expr),
 
   89            ExpressionType.MemberAccess =>
 
   90                MemberAccessExpr((MemberExpression)expr),
 
   91            ExpressionType.MemberInit =>
 
   92                MemberInitExpr((MemberInitExpression)expr),
 
   94                NewExpr((NewExpression)expr),
 
   96            ExpressionType.NewArrayBounds or
 
   97            ExpressionType.NewArrayInit =>
 
   98                NewArrayExpr((NewArrayExpression)expr),
 
  100            ExpressionType.Parameter =>
 
  101                ParameterExpr((ParameterExpression)expr),
 
  102            ExpressionType.RuntimeVariables =>
 
  103                RuntimeVariablesExpr((RuntimeVariablesExpression)expr),
 
  104            ExpressionType.Switch =>
 
  105                SwitchExpr((SwitchExpression)expr),
 
  106            ExpressionType.Try =>
 
  107                TryExpr((TryExpression)expr),
 
  109            ExpressionType.TypeEqual or
 
  110            ExpressionType.TypeIs =>
 
  111                TypeBinaryExpr((TypeBinaryExpression)expr),
 
  113            ExpressionType.Convert or
 
  114            ExpressionType.ConvertChecked or
 
  117                Apply(((UnaryExpression)expr).Operand),
 
  119            ExpressionType.ArrayLength or
 
  120            ExpressionType.Convert or
 
  121            ExpressionType.ConvertChecked or
 
  122            ExpressionType.Decrement or
 
  123            ExpressionType.Increment or
 
  124            ExpressionType.IsFalse or
 
  125            ExpressionType.IsTrue or
 
  126            ExpressionType.Negate or
 
  127            ExpressionType.NegateChecked or
 
  128            ExpressionType.Not or
 
  129            ExpressionType.OnesComplement or
 
  130            ExpressionType.PostDecrementAssign or
 
  131            ExpressionType.PostIncrementAssign or
 
  132            ExpressionType.PreDecrementAssign or
 
  133            ExpressionType.PreIncrementAssign or
 
  134            ExpressionType.Quote or
 
  135            ExpressionType.Throw or
 
  136            ExpressionType.TypeAs or
 
  137            ExpressionType.UnaryPlus or
 
  138            ExpressionType.Unbox =>
 
  139                UnaryExpr((UnaryExpression)expr),
 
  143            ExpressionType.Extension => UnknownExpr(expr)
 
  147    protected abstract TResult NullExpr();
 
  149    protected abstract TResult BinaryExpr(BinaryExpression expr);
 
  150    protected abstract TResult BlockExpr(BlockExpression expr);
 
  151    protected abstract TResult ConditionalExpr(ConditionalExpression expr);
 
  152    protected abstract TResult CallExpr(MethodCallExpression expr);
 
  153    protected abstract TResult ConstantExpr(ConstantExpression expr);
 
  154    protected abstract TResult DebugInfoExpr(DebugInfoExpression expr);
 
  155    protected abstract TResult DefaultExpr(DefaultExpression expr);
 
  156    protected abstract TResult DynamicExpr(DynamicExpression expr);
 
  157    protected abstract TResult GotoExpr(GotoExpression expr);
 
  158    protected abstract TResult IndexExpr(IndexExpression expr);
 
  159    protected abstract TResult InvokeExpr(InvocationExpression expr);
 
  160    protected abstract TResult LabelExpr(LabelExpression expr);
 
  161    protected abstract TResult LambdaExpr(LambdaExpression expr);
 
  162    protected abstract TResult ListInitExpr(ListInitExpression expr);
 
  163    protected abstract TResult LoopExpr(LoopExpression expr);
 
  164    protected abstract TResult MemberAccessExpr(MemberExpression expr);
 
  165    protected abstract TResult MemberInitExpr(MemberInitExpression expr);
 
  166    protected abstract TResult NewArrayExpr(NewArrayExpression expr);
 
  167    protected abstract TResult NewExpr(NewExpression expr);
 
  168    protected abstract TResult ParameterExpr(ParameterExpression expr);
 
  169    protected abstract TResult RuntimeVariablesExpr(RuntimeVariablesExpression expr);
 
  170    protected abstract TResult SwitchExpr(SwitchExpression expr);
 
  171    protected abstract TResult TryExpr(TryExpression expr);
 
  172    protected abstract TResult TypeBinaryExpr(TypeBinaryExpression expr);
 
  173    protected abstract TResult UnaryExpr(UnaryExpression expr);
 
  174    protected abstract TResult UnknownExpr(Expression expr);
 
  177internal class DefaultExpressionSwitch<TResult> : ExpressionSwitch<TResult>
 
  179    protected virtual TResult ApplyDefault(Expression? expr)
 
  180        => 
throw new NotSupportedException($
"Unsupported expression: {expr}");
 
  182    protected override TResult NullExpr() => ApplyDefault(
null);
 
  184    protected override TResult BinaryExpr(BinaryExpression expr) => ApplyDefault(expr);
 
  185    protected override TResult BlockExpr(BlockExpression expr) => ApplyDefault(expr);
 
  186    protected override TResult ConditionalExpr(ConditionalExpression expr) => ApplyDefault(expr);
 
  187    protected override TResult CallExpr(MethodCallExpression expr) => ApplyDefault(expr);
 
  188    protected override TResult ConstantExpr(ConstantExpression expr) => ApplyDefault(expr);
 
  189    protected override TResult DebugInfoExpr(DebugInfoExpression expr) => ApplyDefault(expr);
 
  190    protected override TResult DefaultExpr(DefaultExpression expr) => ApplyDefault(expr);
 
  191    protected override TResult DynamicExpr(DynamicExpression expr) => ApplyDefault(expr);
 
  192    protected override TResult GotoExpr(GotoExpression expr) => ApplyDefault(expr);
 
  193    protected override TResult IndexExpr(IndexExpression expr) => ApplyDefault(expr);
 
  194    protected override TResult InvokeExpr(InvocationExpression expr) => ApplyDefault(expr);
 
  195    protected override TResult LabelExpr(LabelExpression expr) => ApplyDefault(expr);
 
  196    protected override TResult LambdaExpr(LambdaExpression expr) => ApplyDefault(expr);
 
  197    protected override TResult ListInitExpr(ListInitExpression expr) => ApplyDefault(expr);
 
  198    protected override TResult LoopExpr(LoopExpression expr) => ApplyDefault(expr);
 
  199    protected override TResult MemberAccessExpr(MemberExpression expr) => ApplyDefault(expr);
 
  200    protected override TResult MemberInitExpr(MemberInitExpression expr) => ApplyDefault(expr);
 
  201    protected override TResult NewArrayExpr(NewArrayExpression expr) => ApplyDefault(expr);
 
  202    protected override TResult NewExpr(NewExpression expr) => ApplyDefault(expr);
 
  203    protected override TResult ParameterExpr(ParameterExpression expr) => ApplyDefault(expr);
 
  204    protected override TResult RuntimeVariablesExpr(RuntimeVariablesExpression expr) => ApplyDefault(expr);
 
  205    protected override TResult SwitchExpr(SwitchExpression expr) => ApplyDefault(expr);
 
  206    protected override TResult TryExpr(TryExpression expr) => ApplyDefault(expr);
 
  207    protected override TResult TypeBinaryExpr(TypeBinaryExpression expr) => ApplyDefault(expr);
 
  208    protected override TResult UnaryExpr(UnaryExpression expr) => ApplyDefault(expr);
 
  209    protected override TResult UnknownExpr(Expression expr) => ApplyDefault(expr);