1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . Linq . Expressions ;
4
+ using System . Diagnostics . CodeAnalysis ;
5
+ using System . Linq ;
6
+
7
+ #if JETBRAINS_ANNOTATIONS
8
+ using AllowNullAttribute = JetBrains . Annotations . CanBeNullAttribute ;
9
+ using DisallowNullAttribute = JetBrains . Annotations . NotNullAttribute ;
10
+ using AllowItemNullAttribute = JetBrains . Annotations . ItemCanBeNullAttribute ;
11
+ #endif
12
+
13
+ namespace ExpressionTreeToolkit
14
+ {
15
+ public static partial class ExpressionExtensions
16
+ {
17
+ public static IEnumerable < Expression > AsEnumerable ( [ DisallowNull ] this Expression source )
18
+ {
19
+ if ( source == null )
20
+ {
21
+ throw new ArgumentNullException ( nameof ( source ) ) ;
22
+ }
23
+
24
+ return ExpressionIterator ( source ) ;
25
+ }
26
+
27
+ private static IEnumerable < Expression > ExpressionIterator ( [ DisallowNull ] Expression expression )
28
+ {
29
+ if ( expression == null )
30
+ {
31
+ throw new ArgumentNullException ( nameof ( expression ) ) ;
32
+ }
33
+
34
+ switch ( expression . NodeType )
35
+ {
36
+ case ExpressionType . Negate :
37
+ case ExpressionType . NegateChecked :
38
+ case ExpressionType . Not :
39
+ case ExpressionType . Convert :
40
+ case ExpressionType . ConvertChecked :
41
+ case ExpressionType . ArrayLength :
42
+ case ExpressionType . Quote :
43
+ case ExpressionType . TypeAs :
44
+ case ExpressionType . UnaryPlus :
45
+ case ExpressionType . PreIncrementAssign :
46
+ case ExpressionType . PreDecrementAssign :
47
+ case ExpressionType . PostIncrementAssign :
48
+ case ExpressionType . PostDecrementAssign :
49
+ case ExpressionType . IsTrue :
50
+ case ExpressionType . IsFalse :
51
+ case ExpressionType . OnesComplement :
52
+ case ExpressionType . Decrement :
53
+ case ExpressionType . Increment :
54
+ case ExpressionType . Throw :
55
+ case ExpressionType . Unbox :
56
+ return UnaryIterator ( ( UnaryExpression ) expression ) ;
57
+ case ExpressionType . Add :
58
+ case ExpressionType . AddChecked :
59
+ case ExpressionType . Subtract :
60
+ case ExpressionType . SubtractChecked :
61
+ case ExpressionType . Multiply :
62
+ case ExpressionType . MultiplyChecked :
63
+ case ExpressionType . Divide :
64
+ case ExpressionType . Modulo :
65
+ case ExpressionType . And :
66
+ case ExpressionType . AndAlso :
67
+ case ExpressionType . Or :
68
+ case ExpressionType . OrElse :
69
+ case ExpressionType . LessThan :
70
+ case ExpressionType . LessThanOrEqual :
71
+ case ExpressionType . GreaterThan :
72
+ case ExpressionType . GreaterThanOrEqual :
73
+ case ExpressionType . Equal :
74
+ case ExpressionType . NotEqual :
75
+ case ExpressionType . Coalesce :
76
+ case ExpressionType . ArrayIndex :
77
+ case ExpressionType . RightShift :
78
+ case ExpressionType . LeftShift :
79
+ case ExpressionType . ExclusiveOr :
80
+ case ExpressionType . Power :
81
+ case ExpressionType . Assign :
82
+ case ExpressionType . AddAssign :
83
+ case ExpressionType . AndAssign :
84
+ case ExpressionType . DivideAssign :
85
+ case ExpressionType . ExclusiveOrAssign :
86
+ case ExpressionType . LeftShiftAssign :
87
+ case ExpressionType . ModuloAssign :
88
+ case ExpressionType . MultiplyAssign :
89
+ case ExpressionType . OrAssign :
90
+ case ExpressionType . PowerAssign :
91
+ case ExpressionType . RightShiftAssign :
92
+ case ExpressionType . SubtractAssign :
93
+ case ExpressionType . AddAssignChecked :
94
+ case ExpressionType . MultiplyAssignChecked :
95
+ case ExpressionType . SubtractAssignChecked :
96
+ return BinaryIterator ( ( BinaryExpression ) expression ) ;
97
+ case ExpressionType . TypeIs :
98
+ case ExpressionType . TypeEqual :
99
+ return TypeBinaryIterator ( ( TypeBinaryExpression ) expression ) ;
100
+ case ExpressionType . Conditional :
101
+ return ConditionalIterator ( ( ConditionalExpression ) expression ) ;
102
+ case ExpressionType . MemberAccess :
103
+ return MemberIterator ( ( MemberExpression ) expression ) ;
104
+ case ExpressionType . Call :
105
+ return MethodCallIterator ( ( MethodCallExpression ) expression ) ;
106
+ case ExpressionType . Lambda :
107
+ return LambdaIterator ( ( LambdaExpression ) expression ) ;
108
+ case ExpressionType . New :
109
+ return NewIterator ( ( NewExpression ) expression ) ;
110
+ case ExpressionType . NewArrayInit :
111
+ case ExpressionType . NewArrayBounds :
112
+ return NewArrayIterator ( ( NewArrayExpression ) expression ) ;
113
+ case ExpressionType . Invoke :
114
+ return InvocationIterator ( ( InvocationExpression ) expression ) ;
115
+ case ExpressionType . MemberInit :
116
+ return MemberInitIterator ( ( MemberInitExpression ) expression ) ;
117
+ case ExpressionType . ListInit :
118
+ return ListInitIterator ( ( ListInitExpression ) expression ) ;
119
+ case ExpressionType . Block :
120
+ return BlockIterator ( ( BlockExpression ) expression ) ;
121
+ case ExpressionType . DebugInfo :
122
+ return DebugInfoIterator ( ( DebugInfoExpression ) expression ) ;
123
+ case ExpressionType . Dynamic :
124
+ return DynamicIterator ( ( DynamicExpression ) expression ) ;
125
+ case ExpressionType . Goto :
126
+ return GotoIterator ( ( GotoExpression ) expression ) ;
127
+ case ExpressionType . Index :
128
+ return IndexIterator ( ( IndexExpression ) expression ) ;
129
+ case ExpressionType . Label :
130
+ return LabelIterator ( ( LabelExpression ) expression ) ;
131
+ case ExpressionType . RuntimeVariables :
132
+ return RuntimeVariablesIterator ( ( RuntimeVariablesExpression ) expression ) ;
133
+ case ExpressionType . Loop :
134
+ return LoopIterator ( ( LoopExpression ) expression ) ;
135
+ case ExpressionType . Switch :
136
+ return SwitchIterator ( ( SwitchExpression ) expression ) ;
137
+ case ExpressionType . Try :
138
+ return TryIterator ( ( TryExpression ) expression ) ;
139
+ case ExpressionType . Default :
140
+ return DefaultIterator ( ( DefaultExpression ) expression ) ;
141
+ case ExpressionType . Extension :
142
+ return ExtensionIterator ( expression ) ;
143
+ case ExpressionType . Constant :
144
+ case ExpressionType . Parameter :
145
+ default :
146
+ return new [ ] { expression } ;
147
+ }
148
+ }
149
+
150
+ private static IEnumerable < Expression > UnaryIterator ( UnaryExpression expression )
151
+ {
152
+ foreach ( var operand in ExpressionIterator ( expression . Operand ) )
153
+ {
154
+ yield return operand ;
155
+ }
156
+
157
+ yield return expression ;
158
+ }
159
+
160
+ private static IEnumerable < Expression > BinaryIterator ( BinaryExpression expression )
161
+ {
162
+ foreach ( var left in ExpressionIterator ( expression . Left ) )
163
+ {
164
+ yield return left ;
165
+ }
166
+
167
+ foreach ( var right in ExpressionIterator ( expression . Right ) )
168
+ {
169
+ yield return right ;
170
+ }
171
+
172
+ yield return expression ;
173
+ }
174
+
175
+ private static IEnumerable < Expression > TypeBinaryIterator ( TypeBinaryExpression expression )
176
+ {
177
+ foreach ( var subExpression in ExpressionIterator ( expression . Expression ) )
178
+ {
179
+ yield return subExpression ;
180
+ }
181
+
182
+ yield return expression ;
183
+ }
184
+
185
+ private static IEnumerable < Expression > ConditionalIterator ( ConditionalExpression expression )
186
+ {
187
+ foreach ( var test in ExpressionIterator ( expression . Test ) )
188
+ {
189
+ yield return test ;
190
+ }
191
+
192
+ foreach ( var ifTrue in ExpressionIterator ( expression . IfTrue ) )
193
+ {
194
+ yield return ifTrue ;
195
+ }
196
+
197
+ foreach ( var ifFalse in ExpressionIterator ( expression . IfFalse ) )
198
+ {
199
+ yield return ifFalse ;
200
+ }
201
+
202
+ yield return expression ;
203
+ }
204
+
205
+ private static IEnumerable < Expression > MemberIterator ( MemberExpression expression )
206
+ {
207
+ if ( expression . Expression != null )
208
+ {
209
+ foreach ( var subExpression in ExpressionIterator ( expression . Expression ) )
210
+ {
211
+ yield return subExpression ;
212
+ }
213
+ }
214
+
215
+ yield return expression ;
216
+ }
217
+
218
+ private static IEnumerable < Expression > MethodCallIterator ( MethodCallExpression expression )
219
+ {
220
+ if ( expression . Object != null )
221
+ {
222
+ foreach ( var obj in ExpressionIterator ( expression . Object ) )
223
+ {
224
+ yield return obj ;
225
+ }
226
+ }
227
+
228
+ foreach ( var argument in expression . Arguments . SelectMany ( ExpressionIterator ) )
229
+ {
230
+ yield return argument ;
231
+ }
232
+
233
+ yield return expression ;
234
+ }
235
+
236
+ private static IEnumerable < Expression > LambdaIterator ( LambdaExpression expression )
237
+ {
238
+ foreach ( var body in ExpressionIterator ( expression . Body ) )
239
+ {
240
+ yield return body ;
241
+ }
242
+
243
+ foreach ( var parameter in expression . Parameters . SelectMany ( ExpressionIterator ) )
244
+ {
245
+ yield return parameter ;
246
+ }
247
+
248
+ yield return expression ;
249
+ }
250
+
251
+ private static IEnumerable < Expression > NewIterator ( NewExpression expression )
252
+ {
253
+ foreach ( var parameter in expression . Arguments . SelectMany ( ExpressionIterator ) )
254
+ {
255
+ yield return parameter ;
256
+ }
257
+
258
+ yield return expression ;
259
+ }
260
+
261
+ private static IEnumerable < Expression > NewArrayIterator ( NewArrayExpression expression )
262
+ {
263
+ foreach ( var expr in expression . Expressions . SelectMany ( ExpressionIterator ) )
264
+ {
265
+ yield return expr ;
266
+ }
267
+
268
+ yield return expression ;
269
+ }
270
+
271
+ private static IEnumerable < Expression > InvocationIterator ( InvocationExpression expression )
272
+ {
273
+ foreach ( var subExpression in ExpressionIterator ( expression . Expression ) )
274
+ {
275
+ yield return subExpression ;
276
+ }
277
+
278
+ foreach ( var parameter in expression . Arguments . SelectMany ( ExpressionIterator ) )
279
+ {
280
+ yield return parameter ;
281
+ }
282
+
283
+ yield return expression ;
284
+ }
285
+
286
+ private static IEnumerable < Expression > MemberInitIterator ( MemberInitExpression expression )
287
+ {
288
+ throw new NotImplementedException ( ) ;
289
+ }
290
+
291
+ private static IEnumerable < Expression > ListInitIterator ( ListInitExpression expression )
292
+ {
293
+ throw new NotImplementedException ( ) ;
294
+ }
295
+
296
+ private static IEnumerable < Expression > BlockIterator ( BlockExpression expression )
297
+ {
298
+ throw new NotImplementedException ( ) ;
299
+ }
300
+
301
+ private static IEnumerable < Expression > DebugInfoIterator ( DebugInfoExpression expression )
302
+ {
303
+ throw new NotImplementedException ( ) ;
304
+ }
305
+
306
+ private static IEnumerable < Expression > DynamicIterator ( DynamicExpression expression )
307
+ {
308
+ throw new NotImplementedException ( ) ;
309
+ }
310
+
311
+ private static IEnumerable < Expression > GotoIterator ( GotoExpression expression )
312
+ {
313
+ throw new NotImplementedException ( ) ;
314
+ }
315
+
316
+ private static IEnumerable < Expression > IndexIterator ( IndexExpression expression )
317
+ {
318
+ throw new NotImplementedException ( ) ;
319
+ }
320
+
321
+ private static IEnumerable < Expression > LabelIterator ( LabelExpression expression )
322
+ {
323
+ throw new NotImplementedException ( ) ;
324
+ }
325
+
326
+ private static IEnumerable < Expression > RuntimeVariablesIterator ( RuntimeVariablesExpression expression )
327
+ {
328
+ throw new NotImplementedException ( ) ;
329
+ }
330
+
331
+ private static IEnumerable < Expression > LoopIterator ( LoopExpression expression )
332
+ {
333
+ throw new NotImplementedException ( ) ;
334
+ }
335
+
336
+ private static IEnumerable < Expression > SwitchIterator ( SwitchExpression expression )
337
+ {
338
+ throw new NotImplementedException ( ) ;
339
+ }
340
+
341
+ private static IEnumerable < Expression > TryIterator ( TryExpression expression )
342
+ {
343
+ throw new NotImplementedException ( ) ;
344
+ }
345
+
346
+ private static IEnumerable < Expression > DefaultIterator ( DefaultExpression expression )
347
+ {
348
+ yield return expression ;
349
+ }
350
+
351
+ private static IEnumerable < Expression > ExtensionIterator ( Expression expression )
352
+ {
353
+ throw new NotImplementedException ( ) ;
354
+ }
355
+ }
356
+ }
0 commit comments