Skip to content

Commit 84bef8c

Browse files
committed
All current generic type inference tests pass
1 parent 1e89673 commit 84bef8c

File tree

2 files changed

+61
-38
lines changed

2 files changed

+61
-38
lines changed

CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2555,7 +2555,7 @@ ExpressionEvaluator evaluatorForMethodArgs()
25552555
yield return new TestCaseData(new ExpressionEvaluator()
25562556
, "Array.ConvertAll(\"test for Upper\".ToCharArray(), Char.IsUpper)"
25572557
, null)
2558-
.Returns(-1)
2558+
.Returns(Array.ConvertAll("test for Upper".ToCharArray(), Char.IsUpper))
25592559
.SetCategory("Bug resolution")
25602560
.SetCategory("MethodNameAsDelegates");
25612561

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,7 +1928,7 @@ protected virtual bool EvaluateVarOrFunc(string expression, Stack<object> stack,
19281928
object obj = inObject ? stack.Pop() : Context;
19291929
object keepObj = obj;
19301930
Type objType = null;
1931-
Type[] inferedGenericsTypes = null; // obj?.GetType().GenericTypeArguments;
1931+
Type[] inferedGenericsTypes = obj?.GetType().GenericTypeArguments;
19321932
ValueTypeNestingTrace valueTypeNestingTrace = null;
19331933

19341934
if (obj != null && TypesToBlock.Contains(obj.GetType()))
@@ -3424,53 +3424,76 @@ protected virtual MethodInfo TryToCastMethodParametersToMakeItCallable(MethodInf
34243424

34253425
MethodInfo oldMethodInfo = methodInfoToCast;
34263426

3427-
if(methodInfoToCast.IsGenericMethod
3428-
&& methodInfoToCast.ContainsGenericParameters)
3427+
if (!string.IsNullOrEmpty(genericsTypes))
34293428
{
3430-
if(!string.IsNullOrWhiteSpace(genericsTypes))
3431-
{
3432-
methodInfoToCast = MakeConcreteMethodIfGeneric(methodInfoToCast, genericsTypes, inferedGenericsTypes);
3433-
}
3434-
else
3435-
{
3436-
Type[] genericArgsTypes = methodInfoToCast.GetGenericArguments();
3437-
List<Type> inferedTypes = new List<Type>();
3429+
methodInfoToCast = MakeConcreteMethodIfGeneric(methodInfoToCast, genericsTypes, inferedGenericsTypes);
3430+
}
3431+
else if (oldMethodInfo.IsGenericMethod
3432+
&& oldMethodInfo.ContainsGenericParameters)
3433+
{
3434+
Type[] genericArgsTypes = oldMethodInfo.GetGenericArguments();
3435+
List<Type> inferedTypes = new List<Type>();
34383436

3439-
for (int t = 0; t < genericArgsTypes.Length; t++)
3437+
for (int t = 0; t<genericArgsTypes.Length; t++)
3438+
{
3439+
if (genericArgsTypes[t].IsGenericParameter)
34403440
{
3441-
if (genericArgsTypes[t].IsGenericParameter)
3442-
{
3443-
string name = genericArgsTypes[t].Name;
3444-
ParameterInfo[] parameterInfos = methodInfoToCast.GetParameters();
3445-
3446-
ParameterInfo paramsForInference = Array.Find(parameterInfos, p => p.ParameterType.IsGenericParameter
3447-
&& p.ParameterType.Name.Equals(name)
3448-
&& modifiedArgs.Count > p.Position
3449-
&& !modifiedArgs[p.Position].GetType().IsGenericParameter);
3441+
string name = genericArgsTypes[t].Name;
3442+
ParameterInfo[] parameterInfos = oldMethodInfo.GetParameters();
34503443

3451-
if (paramsForInference != null)
3452-
{
3453-
inferedTypes.Add(modifiedArgs[paramsForInference.Position].GetType());
3454-
}
3455-
else
3456-
{
3457-
paramsForInference = Array.Find(parameterInfos, p => p.ParameterType.IsGenericType
3458-
&& p.ParameterType.ContainsGenericParameters
3459-
&& p.ParameterType.GetGenericArguments().Any(subP => subP.Name.Equals(name))
3460-
&& modifiedArgs.Count > p.Position
3461-
&& !modifiedArgs[p.Position].GetType().IsGenericType);
3444+
ParameterInfo paramsForInference = Array.Find(parameterInfos, p => p.ParameterType.IsGenericParameter
3445+
&& p.ParameterType.Name.Equals(name)
3446+
&& modifiedArgs.Count > p.Position
3447+
&& !modifiedArgs[p.Position].GetType().IsGenericParameter);
34623448

3463-
inferedTypes.Add(modifiedArgs[paramsForInference.Position].GetType().GetElementType());
3464-
}
3449+
if (paramsForInference != null)
3450+
{
3451+
inferedTypes.Add(modifiedArgs[paramsForInference.Position].GetType());
34653452
}
34663453
else
34673454
{
3468-
inferedTypes.Add(genericArgsTypes[t]);
3455+
paramsForInference = Array.Find(parameterInfos, p => p.ParameterType.IsGenericType
3456+
&& p.ParameterType.ContainsGenericParameters
3457+
&& p.ParameterType.GetGenericArguments().Any(subP => subP.Name.Equals(name))
3458+
&& modifiedArgs.Count > p.Position
3459+
&& !modifiedArgs[p.Position].GetType().IsGenericType);
3460+
3461+
if (paramsForInference != null)
3462+
{
3463+
if (modifiedArgs[paramsForInference.Position] is MethodsGroupEncaps methodsGroupEncaps)
3464+
{
3465+
if(paramsForInference.ParameterType.Name.StartsWith("Converter"))
3466+
{
3467+
Type specificType = paramsForInference.ParameterType.GetGenericArguments().FirstOrDefault(pType => pType.Name.Equals(name));
3468+
MethodInfo paraMethodInfo = methodsGroupEncaps.MethodsGroup.FirstOrDefault(mi => mi.GetParameters().Length == 1);
3469+
if(specificType != null && specificType.GenericParameterPosition == 0)
3470+
{
3471+
inferedTypes.Add(paraMethodInfo.GetParameters()[0].ParameterType);
3472+
}
3473+
else if(specificType != null && specificType.GenericParameterPosition == 1)
3474+
{
3475+
inferedTypes.Add(paraMethodInfo.ReturnType);
3476+
}
3477+
}
3478+
}
3479+
else
3480+
{
3481+
if(modifiedArgs[paramsForInference.Position].GetType().HasElementType)
3482+
inferedTypes.Add(modifiedArgs[paramsForInference.Position].GetType().GetElementType());
3483+
}
3484+
}
34693485
}
34703486
}
3471-
3472-
methodInfoToCast = MakeConcreteMethodIfGeneric(methodInfoToCast, genericsTypes, inferedTypes.ToArray());
3487+
else
3488+
{
3489+
inferedTypes.Add(genericArgsTypes[t]);
3490+
}
34733491
}
3492+
3493+
if(inferedTypes.Count > 0 && inferedTypes.Count == genericArgsTypes.Length)
3494+
methodInfoToCast = MakeConcreteMethodIfGeneric(oldMethodInfo, genericsTypes, inferedTypes.ToArray());
3495+
else
3496+
methodInfoToCast = MakeConcreteMethodIfGeneric(methodInfoToCast, genericsTypes, inferedGenericsTypes);
34743497
}
34753498

34763499
bool parametersCastOK = true;

0 commit comments

Comments
 (0)