1
1
/******************************************************************************************************
2
2
Title : ExpressionEvaluator (https://github.com/codingseb/ExpressionEvaluator)
3
- Version : 1.3.2.1
4
- (if last digit is not a zero, the version is an intermediate version and can be unstable)
3
+ Version : 1.3.2.2
4
+ (if last digit (the forth) is not a zero, the version is an intermediate version and can be unstable)
5
5
6
6
Author : Coding Seb
7
7
Licence : MIT (https://github.com/codingseb/ExpressionEvaluator/blob/master/LICENSE.md)
@@ -35,6 +35,7 @@ public class ExpressionEvaluator
35
35
private static readonly Regex internalCharRegex = new Regex ( @"^['](\\[']|[^'])*[']" ) ;
36
36
private static readonly Regex indexingBeginningRegex = new Regex ( @"^[?]?\[" ) ;
37
37
private static readonly Regex assignationOrPostFixOperatorRegex = new Regex ( @"^\s*((?<assignmentPrefix>[+\-*/%&|^]|<<|>>)?=(?![=>])|(?<postfixOperator>([+][+]|--)(?![" + diactiticsKeywordsRegexPattern + @"0-9])))" ) ;
38
+ private static readonly Regex genericsDecodeRegex = new Regex ( "[^,<>]+(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?" , RegexOptions . Compiled ) ;
38
39
39
40
private static readonly Regex endOfStringWithDollar = new Regex ( "^([^\" {\\ \\ ]|\\ \\ [\\ \\ \" 0abfnrtv])*[\" {]" ) ;
40
41
private static readonly Regex endOfStringWithoutDollar = new Regex ( "^([^\" \\ \\ ]|\\ \\ [\\ \\ \" 0abfnrtv])*[\" ]" ) ;
@@ -1463,6 +1464,7 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
1463
1464
&& ! operatorsDictionary . ContainsKey ( varFuncMatch . Value . Trim ( ) ) )
1464
1465
{
1465
1466
string varFuncName = varFuncMatch . Groups [ "name" ] . Value ;
1467
+ string genericsTypes = varFuncMatch . Groups [ "isgeneric" ] . Value ;
1466
1468
1467
1469
i += varFuncMatch . Length ;
1468
1470
@@ -1514,7 +1516,7 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
1514
1516
throw new ExpressionEvaluatorSyntaxErrorException ( $ "[{ objType . ToString ( ) } ] object has no Method named \" { varFuncName } \" .") ;
1515
1517
1516
1518
// Standard Instance or public method find
1517
- MethodInfo methodInfo = GetRealMethod ( ref objType , ref obj , varFuncName , flag , oArgs ) ;
1519
+ MethodInfo methodInfo = GetRealMethod ( ref objType , ref obj , varFuncName , flag , oArgs , genericsTypes ) ;
1518
1520
1519
1521
// if not found check if obj is an expandoObject or similar
1520
1522
if ( obj is IDynamicMetaObjectProvider && obj is IDictionary < string , object > dictionaryObject && ( dictionaryObject [ varFuncName ] is InternalDelegate || dictionaryObject [ varFuncName ] is Delegate ) )
@@ -1540,7 +1542,7 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
1540
1542
for ( int e = 0 ; e < StaticTypesForExtensionsMethods . Count && methodInfo == null ; e ++ )
1541
1543
{
1542
1544
Type type = StaticTypesForExtensionsMethods [ e ] ;
1543
- methodInfo = GetRealMethod ( ref type , ref obj , varFuncName , StaticBindingFlag , oArgs ) ;
1545
+ methodInfo = GetRealMethod ( ref type , ref obj , varFuncName , StaticBindingFlag , oArgs , genericsTypes ) ;
1544
1546
}
1545
1547
}
1546
1548
@@ -2353,7 +2355,7 @@ private bool GetLambdaExpression(string expr, Stack<object> stack)
2353
2355
}
2354
2356
}
2355
2357
2356
- private MethodInfo GetRealMethod ( ref Type type , ref object obj , string func , BindingFlags flag , List < object > args )
2358
+ private MethodInfo GetRealMethod ( ref Type type , ref object obj , string func , BindingFlags flag , List < object > args , string genericsTypes = "" )
2357
2359
{
2358
2360
MethodInfo methodInfo = null ;
2359
2361
List < object > modifiedArgs = new List < object > ( args ) ;
@@ -2362,7 +2364,7 @@ private MethodInfo GetRealMethod(ref Type type, ref object obj, string func, Bin
2362
2364
( func . ManageCasing ( OptionCaseSensitiveEvaluationActive ) . StartsWith ( "Fluid" . ManageCasing ( OptionCaseSensitiveEvaluationActive ) )
2363
2365
|| func . ManageCasing ( OptionCaseSensitiveEvaluationActive ) . StartsWith ( "Fluent" . ManageCasing ( OptionCaseSensitiveEvaluationActive ) ) ) )
2364
2366
{
2365
- methodInfo = GetRealMethod ( ref type , ref obj , func . ManageCasing ( OptionCaseSensitiveEvaluationActive ) . Substring ( func . ManageCasing ( OptionCaseSensitiveEvaluationActive ) . StartsWith ( "Fluid" . ManageCasing ( OptionCaseSensitiveEvaluationActive ) ) ? 5 : 6 ) , flag , modifiedArgs ) ;
2367
+ methodInfo = GetRealMethod ( ref type , ref obj , func . ManageCasing ( OptionCaseSensitiveEvaluationActive ) . Substring ( func . ManageCasing ( OptionCaseSensitiveEvaluationActive ) . StartsWith ( "Fluid" . ManageCasing ( OptionCaseSensitiveEvaluationActive ) ) ? 5 : 6 ) , flag , modifiedArgs , genericsTypes ) ;
2366
2368
if ( methodInfo != null )
2367
2369
{
2368
2370
if ( methodInfo . ReturnType == typeof ( void ) )
@@ -2390,7 +2392,7 @@ private MethodInfo GetRealMethod(ref Type type, ref object obj, string func, Bin
2390
2392
2391
2393
if ( methodInfo != null )
2392
2394
{
2393
- methodInfo = MakeConcreteMethodIfGeneric ( methodInfo ) ;
2395
+ methodInfo = MakeConcreteMethodIfGeneric ( methodInfo , genericsTypes ) ;
2394
2396
}
2395
2397
else
2396
2398
{
@@ -2400,7 +2402,7 @@ private MethodInfo GetRealMethod(ref Type type, ref object obj, string func, Bin
2400
2402
2401
2403
for ( int m = 0 ; m < methodInfos . Count && methodInfo == null ; m ++ )
2402
2404
{
2403
- methodInfos [ m ] = MakeConcreteMethodIfGeneric ( methodInfos [ m ] ) ;
2405
+ methodInfos [ m ] = MakeConcreteMethodIfGeneric ( methodInfos [ m ] , genericsTypes ) ;
2404
2406
2405
2407
bool parametersCastOK = true ;
2406
2408
@@ -2463,16 +2465,28 @@ private MethodInfo GetRealMethod(ref Type type, ref object obj, string func, Bin
2463
2465
return methodInfo ;
2464
2466
}
2465
2467
2466
- private MethodInfo MakeConcreteMethodIfGeneric ( MethodInfo methodInfo )
2468
+ private MethodInfo MakeConcreteMethodIfGeneric ( MethodInfo methodInfo , string genericsTypes = "" )
2467
2469
{
2468
2470
if ( methodInfo . IsGenericMethod )
2469
2471
{
2470
- return methodInfo . MakeGenericMethod ( Enumerable . Repeat ( typeof ( object ) , methodInfo . GetGenericArguments ( ) . Count ( ) ) . ToArray ( ) ) ;
2472
+ if ( genericsTypes . Equals ( string . Empty ) )
2473
+ return methodInfo . MakeGenericMethod ( Enumerable . Repeat ( typeof ( object ) , methodInfo . GetGenericArguments ( ) . Count ( ) ) . ToArray ( ) ) ;
2474
+ else
2475
+ return methodInfo . MakeGenericMethod ( GetConcreteTypes ( genericsTypes ) ) ;
2471
2476
}
2472
2477
2473
2478
return methodInfo ;
2474
2479
}
2475
2480
2481
+ private Type [ ] GetConcreteTypes ( string genericsTypes )
2482
+ {
2483
+ return genericsDecodeRegex
2484
+ . Matches ( genericsTypes . TrimStart ( ' ' , '<' ) . TrimEnd ( ' ' , '>' ) )
2485
+ . Cast < Match > ( )
2486
+ . Select ( match => GetTypeByFriendlyName ( match . Value ) )
2487
+ . ToArray ( ) ;
2488
+ }
2489
+
2476
2490
private BindingFlags DetermineInstanceOrStatic ( ref Type objType , ref object obj )
2477
2491
{
2478
2492
if ( obj is ClassOrTypeName classOrTypeName )
0 commit comments