Skip to content

Commit 616548d

Browse files
author
Sébastien Geiser
committed
Optimistic type inference
Increment last digit
1 parent 7b0086d commit 616548d

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,10 @@ public void TypeTesting(string expression, Type type)
957957
[TestCase("new List<string>().GetType()", ExpectedResult = typeof(List<string>), Category = "new Keyword, Generics")]
958958
[TestCase("new Dictionary<string,List<int>>().GetType()", ExpectedResult = typeof(Dictionary<string, List<int>>), Category = "new Keyword, Generics")]
959959

960+
// Linq and Types inference
961+
[TestCase("new List<int>() { 1, 2, 3, 4 }.Where<int>(x => x > 2).Json", ExpectedResult = "[3,4]", Category = "Linq, Lambda, new Keyword, Generics")]
962+
[TestCase("new List<int>() { 1, 2, 3, 4 }.Where(x => x > 2).Json", ExpectedResult = "[3,4]", Category = "Linq, Type inference, Lambda, new Keyword, Generics")]
963+
960964
#endregion
961965

962966
#region Complex expressions

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/******************************************************************************************************
22
Title : ExpressionEvaluator (https://github.com/codingseb/ExpressionEvaluator)
3-
Version : 1.4.1.0
3+
Version : 1.4.1.1
44
(if last digit (the forth) is not a zero, the version is an intermediate version and can be unstable)
55
66
Author : Coding Seb
@@ -1735,6 +1735,7 @@ protected virtual bool EvaluateVarOrFunc(string expression, Stack<object> stack,
17351735
object obj = stack.Pop();
17361736
object keepObj = obj;
17371737
Type objType = null;
1738+
Type[] inferedGenericsTypes = obj.GetType().GenericTypeArguments;
17381739
ValueTypeNestingTrace valueTypeNestingTrace = null;
17391740

17401741
if (obj != null && TypesToBlock.Contains(obj.GetType()))
@@ -1775,7 +1776,7 @@ protected virtual bool EvaluateVarOrFunc(string expression, Stack<object> stack,
17751776
throw new ExpressionEvaluatorSyntaxErrorException($"[{objType}] object has no Method named \"{varFuncName}\".");
17761777

17771778
// Standard Instance or public method find
1778-
MethodInfo methodInfo = GetRealMethod(ref objType, ref obj, varFuncName, flag, oArgs, genericsTypes);
1779+
MethodInfo methodInfo = GetRealMethod(ref objType, ref obj, varFuncName, flag, oArgs, genericsTypes, inferedGenericsTypes);
17791780

17801781
// if not found check if obj is an expandoObject or similar
17811782
if (obj is IDynamicMetaObjectProvider
@@ -1807,7 +1808,7 @@ protected virtual bool EvaluateVarOrFunc(string expression, Stack<object> stack,
18071808
for (int e = 0; e < StaticTypesForExtensionsMethods.Count && methodInfo == null; e++)
18081809
{
18091810
Type type = StaticTypesForExtensionsMethods[e];
1810-
methodInfo = GetRealMethod(ref type, ref extentionObj, varFuncName, StaticBindingFlag, oArgs, genericsTypes);
1811+
methodInfo = GetRealMethod(ref type, ref extentionObj, varFuncName, StaticBindingFlag, oArgs, genericsTypes, inferedGenericsTypes);
18111812
isExtention = methodInfo != null;
18121813
}
18131814
}
@@ -2781,7 +2782,7 @@ protected virtual bool GetLambdaExpression(string expression, Stack<object> stac
27812782
}
27822783
}
27832784

2784-
protected virtual MethodInfo GetRealMethod(ref Type type, ref object obj, string func, BindingFlags flag, List<object> args, string genericsTypes = "")
2785+
protected virtual MethodInfo GetRealMethod(ref Type type, ref object obj, string func, BindingFlags flag, List<object> args, string genericsTypes, Type[] inferedGenericsTypes)
27852786
{
27862787
MethodInfo methodInfo = null;
27872788
List<object> modifiedArgs = new List<object>(args);
@@ -2790,7 +2791,7 @@ protected virtual MethodInfo GetRealMethod(ref Type type, ref object obj, string
27902791
&& (func.StartsWith("Fluid", StringComparisonForCasing)
27912792
|| func.StartsWith("Fluent", StringComparisonForCasing)))
27922793
{
2793-
methodInfo = GetRealMethod(ref type, ref obj, func.Substring(func.StartsWith("Fluid", StringComparisonForCasing) ? 5 : 6), flag, modifiedArgs, genericsTypes);
2794+
methodInfo = GetRealMethod(ref type, ref obj, func.Substring(func.StartsWith("Fluid", StringComparisonForCasing) ? 5 : 6), flag, modifiedArgs, genericsTypes, inferedGenericsTypes);
27942795
if (methodInfo != null)
27952796
{
27962797
if (methodInfo.ReturnType == typeof(void))
@@ -2818,7 +2819,7 @@ protected virtual MethodInfo GetRealMethod(ref Type type, ref object obj, string
28182819

28192820
if (methodInfo != null)
28202821
{
2821-
methodInfo = MakeConcreteMethodIfGeneric(methodInfo, genericsTypes);
2822+
methodInfo = MakeConcreteMethodIfGeneric(methodInfo, genericsTypes, inferedGenericsTypes);
28222823
}
28232824
else
28242825
{
@@ -2828,7 +2829,7 @@ protected virtual MethodInfo GetRealMethod(ref Type type, ref object obj, string
28282829

28292830
for (int m = 0; m < methodInfos.Count && methodInfo == null; m++)
28302831
{
2831-
methodInfos[m] = MakeConcreteMethodIfGeneric(methodInfos[m], genericsTypes);
2832+
methodInfos[m] = MakeConcreteMethodIfGeneric(methodInfos[m], genericsTypes, inferedGenericsTypes);
28322833

28332834
bool parametersCastOK = true;
28342835

@@ -2891,14 +2892,25 @@ protected virtual MethodInfo GetRealMethod(ref Type type, ref object obj, string
28912892
return methodInfo;
28922893
}
28932894

2894-
protected virtual MethodInfo MakeConcreteMethodIfGeneric(MethodInfo methodInfo, string genericsTypes = "")
2895+
protected virtual MethodInfo MakeConcreteMethodIfGeneric(MethodInfo methodInfo, string genericsTypes, Type[] inferedGenericsTypes)
28952896
{
28962897
if (methodInfo.IsGenericMethod)
28972898
{
28982899
if (genericsTypes.Equals(string.Empty))
2899-
return methodInfo.MakeGenericMethod(Enumerable.Repeat(typeof(object), methodInfo.GetGenericArguments().Length).ToArray());
2900+
{
2901+
if(inferedGenericsTypes != null && inferedGenericsTypes.Length == methodInfo.GetGenericArguments().Length)
2902+
{
2903+
return methodInfo.MakeGenericMethod(inferedGenericsTypes);
2904+
}
2905+
else
2906+
{
2907+
return methodInfo.MakeGenericMethod(Enumerable.Repeat(typeof(object), methodInfo.GetGenericArguments().Length).ToArray());
2908+
}
2909+
}
29002910
else
2911+
{
29012912
return methodInfo.MakeGenericMethod(GetConcreteTypes(genericsTypes));
2913+
}
29022914
}
29032915

29042916
return methodInfo;

0 commit comments

Comments
 (0)