Fauna v10 .NET/C# Driver 1.0.0
 
Loading...
Searching...
No Matches
ExpressionSwitch.cs
Go to the documentation of this file.
1using System.Linq.Expressions;
2
3namespace Fauna.Util;
4
5internal abstract class ExpressionSwitch<TResult>
6{
7 // if true, will transparently handle certain node types (Quote, Convert, etc.)
8 protected virtual bool Simplified { get => true; }
9
10 public IEnumerable<TResult> ApplyAll(IEnumerable<Expression> exprs) =>
11 exprs.Select(e => Apply(e));
12
13 // Apply this switch to an expression
14 public TResult Apply(Expression? expr)
15 {
16 if (expr is null) return NullExpr();
17
18 return expr.NodeType switch
19 {
20 ExpressionType.Add or
21 ExpressionType.AddAssign or
22 ExpressionType.AddAssignChecked or
23 ExpressionType.AddChecked or
24 ExpressionType.And 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
48 ExpressionType.Or 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),
60
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),
93 ExpressionType.New =>
94 NewExpr((NewExpression)expr),
95
96 ExpressionType.NewArrayBounds or
97 ExpressionType.NewArrayInit =>
98 NewArrayExpr((NewArrayExpression)expr),
99
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),
108
109 ExpressionType.TypeEqual or
110 ExpressionType.TypeIs =>
111 TypeBinaryExpr((TypeBinaryExpression)expr),
112
113 ExpressionType.Convert or
114 ExpressionType.ConvertChecked or
115 ExpressionType.Quote
116 when Simplified =>
117 Apply(((UnaryExpression)expr).Operand),
118
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),
140
141 // not sure what to do with this one
142
143 ExpressionType.Extension => UnknownExpr(expr)
144 };
145 }
146
147 protected abstract TResult NullExpr();
148
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);
175}
176
177internal class DefaultExpressionSwitch<TResult> : ExpressionSwitch<TResult>
178{
179 protected virtual TResult ApplyDefault(Expression? expr)
180 => throw new NotSupportedException($"Unsupported expression: {expr}");
181
182 protected override TResult NullExpr() => ApplyDefault(null);
183
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);
210}