11/******************************************************************************************************
22 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)
55
66 Author : Coding Seb
77 Licence : MIT (https://github.com/codingseb/ExpressionEvaluator/blob/master/LICENSE.md)
@@ -35,6 +35,7 @@ public class ExpressionEvaluator
3535 private static readonly Regex internalCharRegex = new Regex ( @"^['](\\[']|[^'])*[']" ) ;
3636 private static readonly Regex indexingBeginningRegex = new Regex ( @"^[?]?\[" ) ;
3737 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 ) ;
3839
3940 private static readonly Regex endOfStringWithDollar = new Regex ( "^([^\" {\\ \\ ]|\\ \\ [\\ \\ \" 0abfnrtv])*[\" {]" ) ;
4041 private static readonly Regex endOfStringWithoutDollar = new Regex ( "^([^\" \\ \\ ]|\\ \\ [\\ \\ \" 0abfnrtv])*[\" ]" ) ;
@@ -1463,6 +1464,7 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
14631464 && ! operatorsDictionary . ContainsKey ( varFuncMatch . Value . Trim ( ) ) )
14641465 {
14651466 string varFuncName = varFuncMatch . Groups [ "name" ] . Value ;
1467+ string genericsTypes = varFuncMatch . Groups [ "isgeneric" ] . Value ;
14661468
14671469 i += varFuncMatch . Length ;
14681470
@@ -1514,7 +1516,7 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
15141516 throw new ExpressionEvaluatorSyntaxErrorException ( $ "[{ objType . ToString ( ) } ] object has no Method named \" { varFuncName } \" .") ;
15151517
15161518 // 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 ) ;
15181520
15191521 // if not found check if obj is an expandoObject or similar
15201522 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
15401542 for ( int e = 0 ; e < StaticTypesForExtensionsMethods . Count && methodInfo == null ; e ++ )
15411543 {
15421544 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 ) ;
15441546 }
15451547 }
15461548
@@ -2353,7 +2355,7 @@ private bool GetLambdaExpression(string expr, Stack<object> stack)
23532355 }
23542356 }
23552357
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 = "" )
23572359 {
23582360 MethodInfo methodInfo = null ;
23592361 List < object > modifiedArgs = new List < object > ( args ) ;
@@ -2362,7 +2364,7 @@ private MethodInfo GetRealMethod(ref Type type, ref object obj, string func, Bin
23622364 ( func . ManageCasing ( OptionCaseSensitiveEvaluationActive ) . StartsWith ( "Fluid" . ManageCasing ( OptionCaseSensitiveEvaluationActive ) )
23632365 || func . ManageCasing ( OptionCaseSensitiveEvaluationActive ) . StartsWith ( "Fluent" . ManageCasing ( OptionCaseSensitiveEvaluationActive ) ) ) )
23642366 {
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 ) ;
23662368 if ( methodInfo != null )
23672369 {
23682370 if ( methodInfo . ReturnType == typeof ( void ) )
@@ -2390,7 +2392,7 @@ private MethodInfo GetRealMethod(ref Type type, ref object obj, string func, Bin
23902392
23912393 if ( methodInfo != null )
23922394 {
2393- methodInfo = MakeConcreteMethodIfGeneric ( methodInfo ) ;
2395+ methodInfo = MakeConcreteMethodIfGeneric ( methodInfo , genericsTypes ) ;
23942396 }
23952397 else
23962398 {
@@ -2400,7 +2402,7 @@ private MethodInfo GetRealMethod(ref Type type, ref object obj, string func, Bin
24002402
24012403 for ( int m = 0 ; m < methodInfos . Count && methodInfo == null ; m ++ )
24022404 {
2403- methodInfos [ m ] = MakeConcreteMethodIfGeneric ( methodInfos [ m ] ) ;
2405+ methodInfos [ m ] = MakeConcreteMethodIfGeneric ( methodInfos [ m ] , genericsTypes ) ;
24042406
24052407 bool parametersCastOK = true ;
24062408
@@ -2463,16 +2465,28 @@ private MethodInfo GetRealMethod(ref Type type, ref object obj, string func, Bin
24632465 return methodInfo ;
24642466 }
24652467
2466- private MethodInfo MakeConcreteMethodIfGeneric ( MethodInfo methodInfo )
2468+ private MethodInfo MakeConcreteMethodIfGeneric ( MethodInfo methodInfo , string genericsTypes = "" )
24672469 {
24682470 if ( methodInfo . IsGenericMethod )
24692471 {
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 ) ) ;
24712476 }
24722477
24732478 return methodInfo ;
24742479 }
24752480
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+
24762490 private BindingFlags DetermineInstanceOrStatic ( ref Type objType , ref object obj )
24772491 {
24782492 if ( obj is ClassOrTypeName classOrTypeName )
0 commit comments