1515using System . Globalization ;
1616using System . Linq ;
1717using System . Reflection ;
18+ using System . Runtime . CompilerServices ;
1819using System . Runtime . InteropServices ;
1920using System . Text ;
2021using System . Text . RegularExpressions ;
21- using System . Runtime . CompilerServices ;
2222
2323namespace CodingSeb . ExpressionEvaluator
2424{
@@ -1772,7 +1772,7 @@ void InitSimpleObjet(object element, List<string> initArgs)
17721772 int typeIndex = 0 ;
17731773 Type type = EvaluateType ( completeName + genericTypes , ref typeIndex ) ;
17741774
1775- if ( type == null || typeIndex > 0 && typeIndex < completeName . Length )
1775+ if ( type == null || ( typeIndex > 0 && typeIndex < completeName . Length ) )
17761776 throw new ExpressionEvaluatorSyntaxErrorException ( $ "Type or class { completeName } { genericTypes } is unknown") ;
17771777
17781778 void Init ( object element , List < string > initArgs )
@@ -2159,6 +2159,22 @@ where method.GetParameters()[0].ParameterType == objType // static extMethod(thi
21592159 {
21602160 stack . Push ( delegateVar . DynamicInvoke ( funcArgs . ConvertAll ( Evaluate ) . ToArray ( ) ) ) ;
21612161 }
2162+ else if ( Variables . TryGetValue ( varFuncName , out o ) && o is MethodsGroupEncaps methodsGroupEncaps )
2163+ {
2164+ List < object > args = funcArgs . ConvertAll ( Evaluate ) ;
2165+ List < object > modifiedArgs = null ;
2166+ MethodInfo methodInfo = null ;
2167+
2168+ for ( int m = 0 ; methodInfo == null && m < methodsGroupEncaps . MethodsGroup . Length ; m ++ )
2169+ {
2170+ modifiedArgs = new List < object > ( args ) ;
2171+
2172+ methodInfo = TryToCastMethodParametersToMakeItCallable ( methodsGroupEncaps . MethodsGroup [ m ] , modifiedArgs , genericsTypes , new Type [ 0 ] , methodsGroupEncaps . ContainerObject ) ;
2173+ }
2174+
2175+ if ( methodInfo != null )
2176+ stack . Push ( methodInfo . Invoke ( methodsGroupEncaps . ContainerObject , modifiedArgs ? . ToArray ( ) ) ) ;
2177+ }
21622178 else
21632179 {
21642180 FunctionEvaluationEventArg functionEvaluationEventArg = new FunctionEvaluationEventArg ( varFuncName , funcArgs , this , genericTypes : genericsTypes , evaluateGenericTypes : GetConcreteTypes ) ;
@@ -2249,6 +2265,20 @@ where method.GetParameters()[0].ParameterType == objType // static extMethod(thi
22492265 if ( member == null && ! isDynamic )
22502266 member = objType . GetField ( varFuncName , flag ) ;
22512267
2268+ if ( member == null && ! isDynamic )
2269+ {
2270+ MethodInfo [ ] methodsGroup = objType . GetMember ( varFuncName , flag ) . OfType < MethodInfo > ( ) . ToArray ( ) ;
2271+
2272+ if ( methodsGroup . Length > 0 )
2273+ {
2274+ varValue = new MethodsGroupEncaps ( )
2275+ {
2276+ ContainerObject = obj ,
2277+ MethodsGroup = methodsGroup
2278+ } ;
2279+ }
2280+ }
2281+
22522282 bool pushVarValue = true ;
22532283
22542284 if ( isDynamic )
@@ -3392,6 +3422,8 @@ protected virtual MethodInfo TryToCastMethodParametersToMakeItCallable(MethodInf
33923422 {
33933423 MethodInfo methodInfo = null ;
33943424
3425+ MethodInfo oldMethodInfo = methodInfoToCast ;
3426+
33953427 methodInfoToCast = MakeConcreteMethodIfGeneric ( methodInfoToCast , genericsTypes , inferedGenericsTypes ) ;
33963428
33973429 bool parametersCastOK = true ;
@@ -3416,7 +3448,7 @@ protected virtual MethodInfo TryToCastMethodParametersToMakeItCallable(MethodInf
34163448 && modifiedArgs [ a ] is InternalDelegate )
34173449 {
34183450 InternalDelegate led = modifiedArgs [ a ] as InternalDelegate ;
3419- modifiedArgs [ a ] = new Predicate < object > ( o => ( bool ) ( led ( new object [ ] { o } ) ) ) ;
3451+ modifiedArgs [ a ] = new Predicate < object > ( o => ( bool ) led ( new object [ ] { o } ) ) ;
34203452 }
34213453 else if ( paramTypeName . StartsWith ( "Func" )
34223454 && modifiedArgs [ a ] is InternalDelegate )
@@ -3444,6 +3476,49 @@ protected virtual MethodInfo TryToCastMethodParametersToMakeItCallable(MethodInf
34443476 InternalDelegate led = modifiedArgs [ a ] as InternalDelegate ;
34453477 modifiedArgs [ a ] = new Converter < object , object > ( o => led ( new object [ ] { o } ) ) ;
34463478 }
3479+ else if ( typeof ( Delegate ) . IsAssignableFrom ( parameterType )
3480+ && modifiedArgs [ a ] is MethodsGroupEncaps methodsGroupEncaps )
3481+ {
3482+ MethodInfo invokeMethod = parameterType . GetMethod ( "Invoke" ) ;
3483+ MethodInfo methodForDelegate = Array . Find ( methodsGroupEncaps . MethodsGroup , m => invokeMethod . GetParameters ( ) . Length == m . GetParameters ( ) . Length && invokeMethod . ReturnType . IsAssignableFrom ( m . ReturnType ) ) ;
3484+ if ( methodForDelegate != null )
3485+ {
3486+ Type [ ] parametersTypes = methodForDelegate . GetParameters ( ) . Select ( p => p . ParameterType ) . ToArray ( ) ;
3487+ Type delegateType ;
3488+
3489+ if ( methodForDelegate . ReturnType == typeof ( void ) )
3490+ {
3491+ delegateType = Type . GetType ( $ "System.Action`{ parametersTypes . Length } ") ;
3492+ }
3493+ else if ( paramTypeName . StartsWith ( "Predicate" ) )
3494+ {
3495+ delegateType = typeof ( Predicate < > ) ;
3496+ parametersTypes = parametersTypes . Concat ( new Type [ ] { typeof ( bool ) } ) . ToArray ( ) ;
3497+ }
3498+ else if ( paramTypeName . StartsWith ( "Converter" ) )
3499+ {
3500+ delegateType = typeof ( Converter < , > ) ;
3501+ parametersTypes = parametersTypes . Concat ( new Type [ ] { methodForDelegate . ReturnType } ) . ToArray ( ) ;
3502+ }
3503+ else
3504+ {
3505+ delegateType = Type . GetType ( $ "System.Func`{ parametersTypes . Length + 1 } ") ;
3506+ parametersTypes = parametersTypes . Concat ( new Type [ ] { methodForDelegate . ReturnType } ) . ToArray ( ) ;
3507+ }
3508+
3509+ delegateType = delegateType . MakeGenericType ( parametersTypes ) ;
3510+
3511+ modifiedArgs [ a ] = Delegate . CreateDelegate ( delegateType , methodsGroupEncaps . ContainerObject , methodForDelegate ) ;
3512+
3513+ if ( oldMethodInfo . IsGenericMethod &&
3514+ methodInfoToCast . GetGenericArguments ( ) . Length == parametersTypes . Length &&
3515+ ! methodInfoToCast . GetGenericArguments ( ) . SequenceEqual ( parametersTypes ) &&
3516+ string . IsNullOrWhiteSpace ( genericsTypes ) )
3517+ {
3518+ methodInfoToCast = MakeConcreteMethodIfGeneric ( oldMethodInfo , genericsTypes , parametersTypes ) ;
3519+ }
3520+ }
3521+ }
34473522 else
34483523 {
34493524 try
@@ -3478,7 +3553,7 @@ protected virtual MethodInfo TryToCastMethodParametersToMakeItCallable(MethodInf
34783553 {
34793554 try
34803555 {
3481- ParameterCastEvaluationEventArg parameterCastEvaluationEventArg = new ParameterCastEvaluationEventArg ( methodInfo , parameterType , modifiedArgs [ a ] , a , this , onInstance ) ;
3556+ ParameterCastEvaluationEventArg parameterCastEvaluationEventArg = new ParameterCastEvaluationEventArg ( methodInfoToCast , parameterType , modifiedArgs [ a ] , a , this , onInstance ) ;
34823557
34833558 EvaluateParameterCast ? . Invoke ( this , parameterCastEvaluationEventArg ) ;
34843559
@@ -4299,6 +4374,13 @@ public SubExpression(string expression)
42994374 }
43004375 }
43014376
4377+ public partial class MethodsGroupEncaps
4378+ {
4379+ public object ContainerObject { get ; set ; }
4380+
4381+ public MethodInfo [ ] MethodsGroup { get ; set ; }
4382+ }
4383+
43024384 public partial class BubbleExceptionContainer
43034385 {
43044386 public Exception Exception { get ; set ; }
0 commit comments