@@ -519,13 +519,13 @@ Expression ParseIn()
519
519
var op = _textParser . CurrentToken ;
520
520
521
521
_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)
523
523
{
524
524
while ( _textParser . CurrentToken . Id != TokenId . CloseParen )
525
525
{
526
526
_textParser . NextToken ( ) ;
527
527
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)'
529
529
Expression right = ParseUnary ( ) ;
530
530
531
531
// if the identifier is an Enum, try to convert the right-side also to an Enum.
@@ -537,14 +537,6 @@ Expression ParseIn()
537
537
// else, check for direct type match
538
538
else if ( left . Type != right . Type )
539
539
{
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
-
548
540
CheckAndPromoteOperands ( typeof ( IEqualitySignatures ) , "==" , ref left , ref right , op . Pos ) ;
549
541
}
550
542
@@ -558,32 +550,43 @@ Expression ParseIn()
558
550
}
559
551
560
552
if ( _textParser . CurrentToken . Id == TokenId . End )
553
+ {
561
554
throw ParseError ( op . Pos , Res . CloseParenOrCommaExpected ) ;
555
+ }
562
556
}
563
557
}
564
- else if ( _textParser . CurrentToken . Id == TokenId . Identifier ) //a single argument
558
+ else if ( _textParser . CurrentToken . Id == TokenId . Identifier ) // a single argument
565
559
{
566
560
Expression right = ParsePrimary ( ) ;
567
561
568
562
if ( ! typeof ( IEnumerable ) . IsAssignableFrom ( right . Type ) )
563
+ {
569
564
throw ParseError ( _textParser . CurrentToken . Pos , Res . IdentifierImplementingInterfaceExpected , typeof ( IEnumerable ) ) ;
565
+ }
570
566
571
567
var args = new [ ] { left } ;
572
568
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
+ {
575
571
throw ParseError ( op . Pos , Res . NoApplicableAggregate , "Contains" ) ;
572
+ }
576
573
577
574
var typeArgs = new [ ] { left . Type } ;
575
+
578
576
args = new [ ] { right , left } ;
579
577
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 ) ;
584
585
}
585
586
else
587
+ {
586
588
throw ParseError ( op . Pos , Res . OpenParenOrIdentifierExpected ) ;
589
+ }
587
590
588
591
_textParser . NextToken ( ) ;
589
592
}
@@ -1608,8 +1611,7 @@ static Type FindGenericType(Type generic, Type type)
1608
1611
1609
1612
Type FindType ( string name )
1610
1613
{
1611
- object type ;
1612
- _keywords . TryGetValue ( name , out type ) ;
1614
+ _keywords . TryGetValue ( name , out object type ) ;
1613
1615
var result = type as Type ;
1614
1616
if ( result != null )
1615
1617
return result ;
@@ -1652,9 +1654,10 @@ Expression ParseAggregate(Expression instance, Type elementType, string methodNa
1652
1654
_it = outerIt ;
1653
1655
_parent = oldParent ;
1654
1656
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
+ {
1657
1659
throw ParseError ( errorPos , Res . NoApplicableAggregate , methodName ) ;
1660
+ }
1658
1661
1659
1662
Type [ ] typeArgs ;
1660
1663
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
1704
1707
}
1705
1708
}
1706
1709
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 ) ;
1708
1720
}
1709
1721
1710
1722
Expression [ ] ParseArgumentList ( )
@@ -1738,9 +1750,11 @@ Expression ParseElementAccess(Expression expr)
1738
1750
int errorPos = _textParser . CurrentToken . Pos ;
1739
1751
_textParser . ValidateToken ( TokenId . OpenBracket , Res . OpenParenExpected ) ;
1740
1752
_textParser . NextToken ( ) ;
1753
+
1741
1754
Expression [ ] args = ParseArguments ( ) ;
1742
1755
_textParser . ValidateToken ( TokenId . CloseBracket , Res . CloseBracketOrCommaExpected ) ;
1743
1756
_textParser . NextToken ( ) ;
1757
+
1744
1758
if ( expr . Type . IsArray )
1745
1759
{
1746
1760
if ( expr . Type . GetArrayRank ( ) != 1 || args . Length != 1 )
@@ -1750,20 +1764,17 @@ Expression ParseElementAccess(Expression expr)
1750
1764
throw ParseError ( errorPos , Res . InvalidIndex ) ;
1751
1765
return Expression . ArrayIndex ( expr , index ) ;
1752
1766
}
1753
- else
1767
+
1768
+ switch ( FindIndexer ( expr . Type , args , out var mb ) )
1754
1769
{
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 ) ) ;
1767
1778
}
1768
1779
}
1769
1780
@@ -1844,15 +1855,6 @@ static bool TryGetMemberName(Expression expression, out string memberName)
1844
1855
return true ;
1845
1856
}
1846
1857
#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
-
1856
1858
memberName = null ;
1857
1859
return false ;
1858
1860
}
@@ -1920,8 +1922,7 @@ void CheckAndPromoteOperand(Type signatures, string opName, ref Expression expr,
1920
1922
{
1921
1923
Expression [ ] args = { expr } ;
1922
1924
1923
- MethodBase method ;
1924
- if ( FindMethod ( signatures , "F" , false , args , out method ) != 1 )
1925
+ if ( ! ContainsMethod ( signatures , "F" , false , args ) )
1925
1926
{
1926
1927
throw IncompatibleOperandError ( opName , expr , errorPos ) ;
1927
1928
}
@@ -1983,57 +1984,58 @@ static MemberInfo FindPropertyOrField(Type type, string memberName, bool staticA
1983
1984
#endif
1984
1985
}
1985
1986
1987
+ bool ContainsMethod ( Type type , string methodName , bool staticAccess , Expression [ ] args )
1988
+ {
1989
+ return FindMethod ( type , methodName , staticAccess , args , out var _ ) == 1 ;
1990
+ }
1991
+
1986
1992
int FindMethod ( Type type , string methodName , bool staticAccess , Expression [ ] args , out MethodBase method )
1987
1993
{
1988
1994
#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 ) ;
1991
1996
foreach ( Type t in SelfAndBaseTypes ( type ) )
1992
1997
{
1993
- MemberInfo [ ] members = t . FindMembers ( MemberTypes . Method ,
1994
- flags , Type . FilterNameIgnoreCase , methodName ) ;
1998
+ MemberInfo [ ] members = t . FindMembers ( MemberTypes . Method , flags , Type . FilterNameIgnoreCase , methodName ) ;
1995
1999
int count = FindBestMethod ( members . Cast < MethodBase > ( ) , args , out method ) ;
1996
- if ( count != 0 ) return count ;
2000
+ if ( count != 0 )
2001
+ {
2002
+ return count ;
2003
+ }
1997
2004
}
1998
- method = null ;
1999
- return 0 ;
2000
2005
#else
2001
2006
foreach ( Type t in SelfAndBaseTypes ( type ) )
2002
2007
{
2003
2008
MethodInfo [ ] methods = t . GetTypeInfo ( ) . DeclaredMethods . Where ( x => ( x . IsStatic || ! staticAccess ) && x . Name . ToLowerInvariant ( ) == methodName . ToLowerInvariant ( ) ) . ToArray ( ) ;
2004
2009
int count = FindBestMethod ( methods , args , out method ) ;
2005
- if ( count != 0 ) return count ;
2010
+ if ( count != 0 )
2011
+ {
2012
+ return count ;
2013
+ }
2006
2014
}
2007
-
2015
+ #endif
2008
2016
method = null ;
2009
2017
return 0 ;
2010
- #endif
2011
2018
}
2012
2019
2013
2020
int FindIndexer ( Type type , Expression [ ] args , out MethodBase method )
2014
2021
{
2015
2022
foreach ( Type t in SelfAndBaseTypes ( type ) )
2016
2023
{
2017
- //#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
2018
2024
MemberInfo [ ] members = t . GetDefaultMembers ( ) ;
2019
- //#else
2020
- // MemberInfo[] members = new MemberInfo[0];
2021
- //#endif
2022
2025
if ( members . Length != 0 )
2023
2026
{
2024
- IEnumerable < MethodBase > methods = members
2025
- . OfType < PropertyInfo > ( ) .
2027
+ IEnumerable < MethodBase > methods = members . OfType < PropertyInfo > ( ) .
2026
2028
#if ! ( NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD )
2027
2029
Select ( p => ( MethodBase ) p . GetGetMethod ( ) ) .
2028
2030
Where ( m => m != null ) ;
2029
2031
#else
2030
2032
Select ( p => ( MethodBase ) p . GetMethod ) ;
2031
2033
#endif
2032
-
2033
2034
int count = FindBestMethod ( methods , args , out method ) ;
2034
2035
if ( count != 0 ) return count ;
2035
2036
}
2036
2037
}
2038
+
2037
2039
method = null ;
2038
2040
return 0 ;
2039
2041
}
@@ -2137,8 +2139,7 @@ Expression PromoteExpression(Expression expr, Type type, bool exact, bool conver
2137
2139
}
2138
2140
else
2139
2141
{
2140
- string text ;
2141
- if ( _literals . TryGetValue ( ce , out text ) )
2142
+ if ( _literals . TryGetValue ( ce , out string text ) )
2142
2143
{
2143
2144
Type target = GetNonNullableType ( type ) ;
2144
2145
object value = null ;
0 commit comments