@@ -16,6 +16,73 @@ namespace StringToExpression.LanguageDefinitions
16
16
/// </summary>
17
17
public class ODataFilterLanguage
18
18
{
19
+ /// <summary>
20
+ /// Access to common String Members
21
+ /// </summary>
22
+ protected static class StringMembers
23
+ {
24
+ /// <summary>
25
+ /// The MethodInfo for the StartsWith method
26
+ /// </summary>
27
+ public static MethodInfo StartsWith = Type < string > . Method ( x => x . StartsWith ( default ( string ) ) ) ;
28
+
29
+ /// <summary>
30
+ /// The MethodInfo for the EndsWith method
31
+ /// </summary>
32
+ public static MethodInfo EndsWith = Type < string > . Method ( x => x . EndsWith ( default ( string ) ) ) ;
33
+
34
+ /// <summary>
35
+ /// The MethodInfo for the Contains method
36
+ /// </summary>
37
+ public static MethodInfo Contains = Type < string > . Method ( x => x . Contains ( default ( string ) ) ) ;
38
+
39
+ /// <summary>
40
+ /// The MethodInfo for the ToLower method
41
+ /// </summary>
42
+ public static MethodInfo ToLower = Type < string > . Method ( x => x . ToLower ( ) ) ;
43
+
44
+ /// <summary>
45
+ /// The MethodInfo for the ToUpper method
46
+ /// </summary>
47
+ public static MethodInfo ToUpper = Type < string > . Method ( x => x . ToUpper ( ) ) ;
48
+ }
49
+
50
+ /// <summary>
51
+ /// Access to common DateTime Members
52
+ /// </summary>
53
+ protected static class DateTimeMembers
54
+ {
55
+ /// <summary>
56
+ /// The MemberInfo for the Year property
57
+ /// </summary>
58
+ public static MemberInfo Year = Type < DateTime > . Member ( x => x . Year ) ;
59
+
60
+ /// <summary>
61
+ /// The MemberInfo for the Month property
62
+ /// </summary>
63
+ public static MemberInfo Month = Type < DateTime > . Member ( x => x . Month ) ;
64
+
65
+ /// <summary>
66
+ /// The MemberInfo for the Day property
67
+ /// </summary>
68
+ public static MemberInfo Day = Type < DateTime > . Member ( x => x . Day ) ;
69
+
70
+ /// <summary>
71
+ /// The MemberInfo for the Hour property
72
+ /// </summary>
73
+ public static MemberInfo Hour = Type < DateTime > . Member ( x => x . Hour ) ;
74
+
75
+ /// <summary>
76
+ /// The MemberInfo for the Minute property
77
+ /// </summary>
78
+ public static MemberInfo Minute = Type < DateTime > . Member ( x => x . Minute ) ;
79
+
80
+ /// <summary>
81
+ /// The MemberInfo for the Second property
82
+ /// </summary>
83
+ public static MemberInfo Second = Type < DateTime > . Member ( x => x . Second ) ;
84
+ }
85
+
19
86
private readonly Language language ;
20
87
21
88
/// <summary>
@@ -144,12 +211,12 @@ protected virtual IEnumerable<GrammerDefinition> LogicalOperatorDefinitions()
144
211
name : "EQ" ,
145
212
regex : @"eq" ,
146
213
orderOfPrecedence : 11 ,
147
- expressionBuilder : ( left , right ) => Expression . Equal ( left , right ) ) ,
214
+ expressionBuilder : ConvertEnumsIfRequired ( ( left , right ) => Expression . Equal ( left , right ) ) ) ,
148
215
new BinaryOperatorDefinition (
149
216
name : "NE" ,
150
217
regex : @"ne" ,
151
218
orderOfPrecedence : 12 ,
152
- expressionBuilder : ( left , right ) => Expression . NotEqual ( left , right ) ) ,
219
+ expressionBuilder : ConvertEnumsIfRequired ( ( left , right ) => Expression . NotEqual ( left , right ) ) ) ,
153
220
154
221
new BinaryOperatorDefinition (
155
222
name : "GT" ,
@@ -271,7 +338,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
271
338
expressionBuilder : ( parameters ) => {
272
339
return Expression . Call (
273
340
instance : parameters [ 0 ] ,
274
- method : Type < string > . Method ( x => x . StartsWith ( null ) ) ,
341
+ method : StringMembers . StartsWith ,
275
342
arguments : new [ ] { parameters [ 1 ] } ) ;
276
343
} ) ,
277
344
new FunctionCallDefinition (
@@ -281,7 +348,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
281
348
expressionBuilder : ( parameters ) => {
282
349
return Expression . Call (
283
350
instance : parameters [ 0 ] ,
284
- method : Type < string > . Method ( x => x . EndsWith ( null ) ) ,
351
+ method : StringMembers . EndsWith ,
285
352
arguments : new [ ] { parameters [ 1 ] } ) ;
286
353
} ) ,
287
354
new FunctionCallDefinition (
@@ -291,7 +358,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
291
358
expressionBuilder : ( parameters ) => {
292
359
return Expression . Call (
293
360
instance : parameters [ 1 ] ,
294
- method : Type < string > . Method ( x => x . Contains ( null ) ) ,
361
+ method : StringMembers . Contains ,
295
362
arguments : new [ ] { parameters [ 0 ] } ) ;
296
363
} ) ,
297
364
new FunctionCallDefinition (
@@ -301,7 +368,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
301
368
expressionBuilder : ( parameters ) => {
302
369
return Expression . Call (
303
370
instance : parameters [ 0 ] ,
304
- method : Type < string > . Method ( x => x . ToLower ( ) ) ) ;
371
+ method : StringMembers . ToLower ) ;
305
372
} ) ,
306
373
new FunctionCallDefinition (
307
374
name : "FN_TOUPPER" ,
@@ -310,7 +377,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
310
377
expressionBuilder : ( parameters ) => {
311
378
return Expression . Call (
312
379
instance : parameters [ 0 ] ,
313
- method : Type < string > . Method ( x => x . ToUpper ( ) ) ) ;
380
+ method : StringMembers . ToUpper ) ;
314
381
} ) ,
315
382
316
383
new FunctionCallDefinition (
@@ -320,7 +387,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
320
387
expressionBuilder : ( parameters ) => {
321
388
return Expression . MakeMemberAccess (
322
389
parameters [ 0 ] ,
323
- Type < DateTime > . Member ( x => x . Day ) ) ;
390
+ DateTimeMembers . Day ) ;
324
391
} ) ,
325
392
new FunctionCallDefinition (
326
393
name : "FN_HOUR" ,
@@ -329,7 +396,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
329
396
expressionBuilder : ( parameters ) => {
330
397
return Expression . MakeMemberAccess (
331
398
parameters [ 0 ] ,
332
- Type < DateTime > . Member ( x => x . Hour ) ) ;
399
+ DateTimeMembers . Hour ) ;
333
400
} ) ,
334
401
new FunctionCallDefinition (
335
402
name : "FN_MINUTE" ,
@@ -338,7 +405,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
338
405
expressionBuilder : ( parameters ) => {
339
406
return Expression . MakeMemberAccess (
340
407
parameters [ 0 ] ,
341
- Type < DateTime > . Member ( x => x . Minute ) ) ;
408
+ DateTimeMembers . Minute ) ;
342
409
} ) ,
343
410
new FunctionCallDefinition (
344
411
name : "FN_MONTH" ,
@@ -347,7 +414,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
347
414
expressionBuilder : ( parameters ) => {
348
415
return Expression . MakeMemberAccess (
349
416
parameters [ 0 ] ,
350
- Type < DateTime > . Member ( x => x . Month ) ) ;
417
+ DateTimeMembers . Month ) ;
351
418
} ) ,
352
419
new FunctionCallDefinition (
353
420
name : "FN_YEAR" ,
@@ -356,7 +423,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
356
423
expressionBuilder : ( parameters ) => {
357
424
return Expression . MakeMemberAccess (
358
425
parameters [ 0 ] ,
359
- Type < DateTime > . Member ( x => x . Year ) ) ;
426
+ DateTimeMembers . Year ) ;
360
427
} ) ,
361
428
new FunctionCallDefinition (
362
429
name : "FN_SECOND" ,
@@ -365,7 +432,7 @@ protected virtual IEnumerable<FunctionCallDefinition> FunctionDefinitions()
365
432
expressionBuilder : ( parameters ) => {
366
433
return Expression . MakeMemberAccess (
367
434
parameters [ 0 ] ,
368
- Type < DateTime > . Member ( x => x . Second ) ) ;
435
+ DateTimeMembers . Second ) ;
369
436
} ) ,
370
437
} ;
371
438
}
@@ -401,6 +468,20 @@ protected virtual IEnumerable<GrammerDefinition> WhitespaceDefinitions()
401
468
}
402
469
403
470
404
-
471
+ /// <summary>
472
+ /// Wraps the function to convert any constants to enums if required
473
+ /// </summary>
474
+ /// <param name="expFn">Function to wrap</param>
475
+ /// <returns></returns>
476
+ protected Func < Expression , Expression , Expression > ConvertEnumsIfRequired ( Func < Expression , Expression , Expression > expFn )
477
+ {
478
+ return ( left , right ) =>
479
+ {
480
+ var didConvertEnum = ExpressionConversions . TryEnumNumberConvert ( ref left , ref right )
481
+ || ExpressionConversions . TryEnumStringConvert ( ref left , ref right , ignoreCase : true ) ;
482
+
483
+ return expFn ( left , right ) ;
484
+ } ;
485
+ }
405
486
}
406
487
}
0 commit comments