Skip to content

Commit 0f5a0be

Browse files
committed
Fix code (#115)
1 parent 60d4c38 commit 0f5a0be

File tree

4 files changed

+73
-72
lines changed

4 files changed

+73
-72
lines changed

src/System.Linq.Dynamic.Core/ExpressionParser.cs

+66-65
Original file line numberDiff line numberDiff line change
@@ -519,13 +519,13 @@ Expression ParseIn()
519519
var op = _textParser.CurrentToken;
520520

521521
_textParser.NextToken();
522-
if (_textParser.CurrentToken.Id == TokenId.OpenParen) //literals (or other inline list)
522+
if (_textParser.CurrentToken.Id == TokenId.OpenParen) // literals (or other inline list)
523523
{
524524
while (_textParser.CurrentToken.Id != TokenId.CloseParen)
525525
{
526526
_textParser.NextToken();
527527

528-
//we need to parse unary expressions because otherwise 'in' clause will fail in use cases like 'in (-1, -1)' or 'in (!true)'
528+
// we need to parse unary expressions because otherwise 'in' clause will fail in use cases like 'in (-1, -1)' or 'in (!true)'
529529
Expression right = ParseUnary();
530530

531531
// if the identifier is an Enum, try to convert the right-side also to an Enum.
@@ -537,14 +537,6 @@ Expression ParseIn()
537537
// else, check for direct type match
538538
else if (left.Type != right.Type)
539539
{
540-
//check for nullable type match
541-
//if (!left.Type.GetTypeInfo().IsGenericType ||
542-
// left.Type.GetGenericTypeDefinition() != typeof(Nullable<>) ||
543-
// left.Type.GetTypeInfo().GetGenericTypeArguments()[0] != right.Type)
544-
//{
545-
// throw ParseError(op.Pos, Res.ExpressionTypeMismatch, left.Type);
546-
//}
547-
548540
CheckAndPromoteOperands(typeof(IEqualitySignatures), "==", ref left, ref right, op.Pos);
549541
}
550542

@@ -558,32 +550,43 @@ Expression ParseIn()
558550
}
559551

560552
if (_textParser.CurrentToken.Id == TokenId.End)
553+
{
561554
throw ParseError(op.Pos, Res.CloseParenOrCommaExpected);
555+
}
562556
}
563557
}
564-
else if (_textParser.CurrentToken.Id == TokenId.Identifier) //a single argument
558+
else if (_textParser.CurrentToken.Id == TokenId.Identifier) // a single argument
565559
{
566560
Expression right = ParsePrimary();
567561

568562
if (!typeof(IEnumerable).IsAssignableFrom(right.Type))
563+
{
569564
throw ParseError(_textParser.CurrentToken.Pos, Res.IdentifierImplementingInterfaceExpected, typeof(IEnumerable));
565+
}
570566

571567
var args = new[] { left };
572568

573-
MethodBase containsSignature;
574-
if (FindMethod(typeof(IEnumerableSignatures), "Contains", false, args, out containsSignature) != 1)
569+
if (FindMethod(typeof(IEnumerableSignatures), "Contains", false, args, out MethodBase containsSignature) != 1)
570+
{
575571
throw ParseError(op.Pos, Res.NoApplicableAggregate, "Contains");
572+
}
576573

577574
var typeArgs = new[] { left.Type };
575+
578576
args = new[] { right, left };
579577

580-
var enumerableType = typeof(Enumerable);
581-
if (!typeof(IQueryable).IsAssignableFrom(right.Type))
582-
enumerableType = typeof(Queryable);
583-
accumulate = Expression.Call(enumerableType, containsSignature.Name, typeArgs, args);
578+
Type callType = typeof(Enumerable);
579+
if (!typeof(IQueryable).IsAssignableFrom(right.Type) && ContainsMethod(typeof(Queryable), containsSignature.Name, false, args))
580+
{
581+
callType = typeof(Queryable);
582+
}
583+
584+
accumulate = Expression.Call(callType, containsSignature.Name, typeArgs, args);
584585
}
585586
else
587+
{
586588
throw ParseError(op.Pos, Res.OpenParenOrIdentifierExpected);
589+
}
587590

588591
_textParser.NextToken();
589592
}
@@ -1608,8 +1611,7 @@ static Type FindGenericType(Type generic, Type type)
16081611

16091612
Type FindType(string name)
16101613
{
1611-
object type;
1612-
_keywords.TryGetValue(name, out type);
1614+
_keywords.TryGetValue(name, out object type);
16131615
var result = type as Type;
16141616
if (result != null)
16151617
return result;
@@ -1652,9 +1654,10 @@ Expression ParseAggregate(Expression instance, Type elementType, string methodNa
16521654
_it = outerIt;
16531655
_parent = oldParent;
16541656

1655-
MethodBase signature;
1656-
if (FindMethod(typeof(IEnumerableSignatures), methodName, false, args, out signature) != 1)
1657+
if (FindMethod(typeof(IEnumerableSignatures), methodName, false, args, out MethodBase signature) != 1)
1658+
{
16571659
throw ParseError(errorPos, Res.NoApplicableAggregate, methodName);
1660+
}
16581661

16591662
Type[] typeArgs;
16601663
if (new[] { "Min", "Max", "Select", "OrderBy", "OrderByDescending", "ThenBy", "ThenByDescending", "GroupBy" }.Contains(signature.Name))
@@ -1704,7 +1707,16 @@ Expression ParseAggregate(Expression instance, Type elementType, string methodNa
17041707
}
17051708
}
17061709

1707-
return Expression.Call(isQueryable ? typeof(Queryable) : typeof(Enumerable), signature.Name, typeArgs, args);
1710+
Type callType = typeof(Enumerable);
1711+
if (isQueryable)
1712+
{
1713+
if (ContainsMethod(typeof(Queryable), signature.Name, false, args))
1714+
{
1715+
callType = typeof(Queryable);
1716+
}
1717+
}
1718+
1719+
return Expression.Call(callType, signature.Name, typeArgs, args);
17081720
}
17091721

17101722
Expression[] ParseArgumentList()
@@ -1738,9 +1750,11 @@ Expression ParseElementAccess(Expression expr)
17381750
int errorPos = _textParser.CurrentToken.Pos;
17391751
_textParser.ValidateToken(TokenId.OpenBracket, Res.OpenParenExpected);
17401752
_textParser.NextToken();
1753+
17411754
Expression[] args = ParseArguments();
17421755
_textParser.ValidateToken(TokenId.CloseBracket, Res.CloseBracketOrCommaExpected);
17431756
_textParser.NextToken();
1757+
17441758
if (expr.Type.IsArray)
17451759
{
17461760
if (expr.Type.GetArrayRank() != 1 || args.Length != 1)
@@ -1750,20 +1764,17 @@ Expression ParseElementAccess(Expression expr)
17501764
throw ParseError(errorPos, Res.InvalidIndex);
17511765
return Expression.ArrayIndex(expr, index);
17521766
}
1753-
else
1767+
1768+
switch (FindIndexer(expr.Type, args, out var mb))
17541769
{
1755-
MethodBase mb;
1756-
switch (FindIndexer(expr.Type, args, out mb))
1757-
{
1758-
case 0:
1759-
throw ParseError(errorPos, Res.NoApplicableIndexer,
1760-
GetTypeName(expr.Type));
1761-
case 1:
1762-
return Expression.Call(expr, (MethodInfo)mb, args);
1763-
default:
1764-
throw ParseError(errorPos, Res.AmbiguousIndexerInvocation,
1765-
GetTypeName(expr.Type));
1766-
}
1770+
case 0:
1771+
throw ParseError(errorPos, Res.NoApplicableIndexer,
1772+
GetTypeName(expr.Type));
1773+
case 1:
1774+
return Expression.Call(expr, (MethodInfo)mb, args);
1775+
default:
1776+
throw ParseError(errorPos, Res.AmbiguousIndexerInvocation,
1777+
GetTypeName(expr.Type));
17671778
}
17681779
}
17691780

@@ -1844,15 +1855,6 @@ static bool TryGetMemberName(Expression expression, out string memberName)
18441855
return true;
18451856
}
18461857
#endif
1847-
//#if !NET35
1848-
// var dynamicExpression = expression as Expressions.DynamicExpression;
1849-
// if (dynamicExpression != null)
1850-
// {
1851-
// memberName = ((GetMemberBinder)dynamicExpression.Binder).Name;
1852-
// return true;
1853-
// }
1854-
//#endif
1855-
18561858
memberName = null;
18571859
return false;
18581860
}
@@ -1920,8 +1922,7 @@ void CheckAndPromoteOperand(Type signatures, string opName, ref Expression expr,
19201922
{
19211923
Expression[] args = { expr };
19221924

1923-
MethodBase method;
1924-
if (FindMethod(signatures, "F", false, args, out method) != 1)
1925+
if (!ContainsMethod(signatures, "F", false, args))
19251926
{
19261927
throw IncompatibleOperandError(opName, expr, errorPos);
19271928
}
@@ -1983,57 +1984,58 @@ static MemberInfo FindPropertyOrField(Type type, string memberName, bool staticA
19831984
#endif
19841985
}
19851986

1987+
bool ContainsMethod(Type type, string methodName, bool staticAccess, Expression[] args)
1988+
{
1989+
return FindMethod(type, methodName, staticAccess, args, out var _) == 1;
1990+
}
1991+
19861992
int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method)
19871993
{
19881994
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
1989-
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
1990-
(staticAccess ? BindingFlags.Static : BindingFlags.Instance);
1995+
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly | (staticAccess ? BindingFlags.Static : BindingFlags.Instance);
19911996
foreach (Type t in SelfAndBaseTypes(type))
19921997
{
1993-
MemberInfo[] members = t.FindMembers(MemberTypes.Method,
1994-
flags, Type.FilterNameIgnoreCase, methodName);
1998+
MemberInfo[] members = t.FindMembers(MemberTypes.Method, flags, Type.FilterNameIgnoreCase, methodName);
19951999
int count = FindBestMethod(members.Cast<MethodBase>(), args, out method);
1996-
if (count != 0) return count;
2000+
if (count != 0)
2001+
{
2002+
return count;
2003+
}
19972004
}
1998-
method = null;
1999-
return 0;
20002005
#else
20012006
foreach (Type t in SelfAndBaseTypes(type))
20022007
{
20032008
MethodInfo[] methods = t.GetTypeInfo().DeclaredMethods.Where(x => (x.IsStatic || !staticAccess) && x.Name.ToLowerInvariant() == methodName.ToLowerInvariant()).ToArray();
20042009
int count = FindBestMethod(methods, args, out method);
2005-
if (count != 0) return count;
2010+
if (count != 0)
2011+
{
2012+
return count;
2013+
}
20062014
}
2007-
2015+
#endif
20082016
method = null;
20092017
return 0;
2010-
#endif
20112018
}
20122019

20132020
int FindIndexer(Type type, Expression[] args, out MethodBase method)
20142021
{
20152022
foreach (Type t in SelfAndBaseTypes(type))
20162023
{
2017-
//#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
20182024
MemberInfo[] members = t.GetDefaultMembers();
2019-
//#else
2020-
// MemberInfo[] members = new MemberInfo[0];
2021-
//#endif
20222025
if (members.Length != 0)
20232026
{
2024-
IEnumerable<MethodBase> methods = members
2025-
.OfType<PropertyInfo>().
2027+
IEnumerable<MethodBase> methods = members.OfType<PropertyInfo>().
20262028
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
20272029
Select(p => (MethodBase)p.GetGetMethod()).
20282030
Where(m => m != null);
20292031
#else
20302032
Select(p => (MethodBase)p.GetMethod);
20312033
#endif
2032-
20332034
int count = FindBestMethod(methods, args, out method);
20342035
if (count != 0) return count;
20352036
}
20362037
}
2038+
20372039
method = null;
20382040
return 0;
20392041
}
@@ -2137,8 +2139,7 @@ Expression PromoteExpression(Expression expr, Type type, bool exact, bool conver
21372139
}
21382140
else
21392141
{
2140-
string text;
2141-
if (_literals.TryGetValue(ce, out text))
2142+
if (_literals.TryGetValue(ce, out string text))
21422143
{
21432144
Type target = GetNonNullableType(type);
21442145
object value = null;

test/System.Linq.Dynamic.Core.Tests/EntitiesTests.Page.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public void Entities_Page()
2222
var result = queryable.Page(page, pageSize).ToDynamicArray<Blog>();
2323

2424
//Assert
25-
Assert.Equal(true, any);
25+
Assert.True(any);
2626
Assert.Equal(total, count);
2727
Assert.Equal(expected, result);
2828
}
@@ -51,4 +51,4 @@ public void Entities_PageResult()
5151
Assert.Equal(expectedResult, result.Queryable.ToDynamicArray<Blog>());
5252
}
5353
}
54-
}
54+
}

test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public void ExpressionTests_ArrayInitializer()
8787
var result4 = list.AsQueryable().SelectMany("new[] { new[] { it + 1, it + 2 }, new[] { it + 3, it + 4 } }");
8888

8989
//Assert
90-
Assert.Equal(result1.Count(), 0);
90+
Assert.Equal(0, result1.Count());
9191
Assert.Equal(result2.Cast<int>(), list.SelectMany(item => new[] { item + 1, item + 2 }));
9292
Assert.Equal(result3.Cast<long>(), list.SelectMany(item => new long[] { item + 1, (byte)(item + 2), (short)(item + 3) }));
9393
Assert.Equal(result4.SelectMany("it").Cast<int>(), list.SelectMany(item => new[] { new[] { item + 1, item + 2 }, new[] { item + 3, item + 4 } }).SelectMany(item => item));
@@ -1547,7 +1547,7 @@ public void ExpressionTests_Uri()
15471547
var result1 = qry.AsQueryable().Where("it = @0", new Uri("http://127.0.0.1"));
15481548

15491549
//Assert
1550-
Assert.Equal(result1.Count(), 2);
1550+
Assert.Equal(2, result1.Count());
15511551
}
15521552

15531553
/// <summary>

test/System.Linq.Dynamic.Core.Tests/QueryableTests.GroupByMany.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ public void GroupByMany_Dynamic_LambdaExpressions()
2222

2323
var sel = lst.AsQueryable().GroupByMany(x => x.Item1, x => x.Item2);
2424

25-
Assert.Equal(sel.Count(), 2);
26-
Assert.Equal(sel.First().Subgroups.Count(), 1);
27-
Assert.Equal(sel.Skip(1).First().Subgroups.Count(), 2);
25+
Assert.Equal(2, sel.Count());
26+
Assert.Equal(1, sel.First().Subgroups.Count());
27+
Assert.Equal(2, sel.Skip(1).First().Subgroups.Count());
2828
}
2929

3030
[Fact]

0 commit comments

Comments
 (0)