@@ -251,7 +251,7 @@ Expression ParseOrOperator()
251
251
Token op = _textParser . CurrentToken ;
252
252
_textParser . NextToken ( ) ;
253
253
Expression right = ParseAndOperator ( ) ;
254
- CheckAndPromoteOperands ( typeof ( ILogicalSignatures ) , op . Text , ref left , ref right , op . Pos ) ;
254
+ CheckAndPromoteOperands ( typeof ( ILogicalSignatures ) , op . Id , op . Text , ref left , ref right , op . Pos ) ;
255
255
left = Expression . OrElse ( left , right ) ;
256
256
}
257
257
return left ;
@@ -266,7 +266,7 @@ Expression ParseAndOperator()
266
266
Token op = _textParser . CurrentToken ;
267
267
_textParser . NextToken ( ) ;
268
268
Expression right = ParseComparisonOperator ( ) ;
269
- CheckAndPromoteOperands ( typeof ( ILogicalSignatures ) , op . Text , ref left , ref right , op . Pos ) ;
269
+ CheckAndPromoteOperands ( typeof ( ILogicalSignatures ) , op . Id , op . Text , ref left , ref right , op . Pos ) ;
270
270
left = Expression . AndAlso ( left , right ) ;
271
271
}
272
272
return left ;
@@ -303,7 +303,7 @@ Expression ParseIn()
303
303
// else, check for direct type match
304
304
else if ( left . Type != right . Type )
305
305
{
306
- CheckAndPromoteOperands ( typeof ( IEqualitySignatures ) , "==" , ref left , ref right , op . Pos ) ;
306
+ CheckAndPromoteOperands ( typeof ( IEqualitySignatures ) , TokenId . DoubleEqual , "==" , ref left , ref right , op . Pos ) ;
307
307
}
308
308
309
309
if ( accumulate . Type != typeof ( bool ) )
@@ -508,7 +508,7 @@ Expression ParseComparisonOperator()
508
508
}
509
509
else
510
510
{
511
- CheckAndPromoteOperands ( isEquality ? typeof ( IEqualitySignatures ) : typeof ( IRelationalSignatures ) , op . Text , ref left , ref right , op . Pos ) ;
511
+ CheckAndPromoteOperands ( isEquality ? typeof ( IEqualitySignatures ) : typeof ( IRelationalSignatures ) , op . Id , op . Text , ref left , ref right , op . Pos ) ;
512
512
}
513
513
}
514
514
}
@@ -589,11 +589,11 @@ Expression ParseShiftOperator()
589
589
switch ( op . Id )
590
590
{
591
591
case TokenId . DoubleLessThan :
592
- CheckAndPromoteOperands ( typeof ( IShiftSignatures ) , op . Text , ref left , ref right , op . Pos ) ;
592
+ CheckAndPromoteOperands ( typeof ( IShiftSignatures ) , op . Id , op . Text , ref left , ref right , op . Pos ) ;
593
593
left = Expression . LeftShift ( left , right ) ;
594
594
break ;
595
595
case TokenId . DoubleGreaterThan :
596
- CheckAndPromoteOperands ( typeof ( IShiftSignatures ) , op . Text , ref left , ref right , op . Pos ) ;
596
+ CheckAndPromoteOperands ( typeof ( IShiftSignatures ) , op . Id , op . Text , ref left , ref right , op . Pos ) ;
597
597
left = Expression . RightShift ( left , right ) ;
598
598
break ;
599
599
}
@@ -619,12 +619,12 @@ Expression ParseAdditive()
619
619
}
620
620
else
621
621
{
622
- CheckAndPromoteOperands ( typeof ( IAddSignatures ) , op . Text , ref left , ref right , op . Pos ) ;
622
+ CheckAndPromoteOperands ( typeof ( IAddSignatures ) , op . Id , op . Text , ref left , ref right , op . Pos ) ;
623
623
left = _expressionHelper . GenerateAdd ( left , right ) ;
624
624
}
625
625
break ;
626
626
case TokenId . Minus :
627
- CheckAndPromoteOperands ( typeof ( ISubtractSignatures ) , op . Text , ref left , ref right , op . Pos ) ;
627
+ CheckAndPromoteOperands ( typeof ( ISubtractSignatures ) , op . Id , op . Text , ref left , ref right , op . Pos ) ;
628
628
left = _expressionHelper . GenerateSubtract ( left , right ) ;
629
629
break ;
630
630
}
@@ -642,7 +642,7 @@ Expression ParseMultiplicative()
642
642
Token op = _textParser . CurrentToken ;
643
643
_textParser . NextToken ( ) ;
644
644
Expression right = ParseUnary ( ) ;
645
- CheckAndPromoteOperands ( typeof ( IArithmeticSignatures ) , op . Text , ref left , ref right , op . Pos ) ;
645
+ CheckAndPromoteOperands ( typeof ( IArithmeticSignatures ) , op . Id , op . Text , ref left , ref right , op . Pos ) ;
646
646
switch ( op . Id )
647
647
{
648
648
case TokenId . Asterisk :
@@ -1897,11 +1897,36 @@ void CheckAndPromoteOperand(Type signatures, string opName, ref Expression expr,
1897
1897
expr = args [ 0 ] ;
1898
1898
}
1899
1899
1900
- void CheckAndPromoteOperands ( Type signatures , string opName , ref Expression left , ref Expression right , int errorPos )
1900
+ static string GetOverloadedOperationName ( TokenId tokenId )
1901
+ {
1902
+ switch ( tokenId )
1903
+ {
1904
+ case TokenId . DoubleEqual :
1905
+ return "op_Equality" ;
1906
+ case TokenId . ExclamationEqual :
1907
+ return "op_Inequality" ;
1908
+ default :
1909
+ return null ;
1910
+ }
1911
+ }
1912
+
1913
+ void CheckAndPromoteOperands ( Type signatures , TokenId opId , string opName , ref Expression left , ref Expression right , int errorPos )
1901
1914
{
1902
1915
Expression [ ] args = { left , right } ;
1916
+
1917
+ // support operator overloading
1918
+ var nativeOperation = GetOverloadedOperationName ( opId ) ;
1919
+ bool found = false ;
1903
1920
1904
- if ( ! _methodFinder . ContainsMethod ( signatures , "F" , false , args ) )
1921
+ if ( nativeOperation != null )
1922
+ {
1923
+ // first try left operand's equality operators
1924
+ found = _methodFinder . ContainsMethod ( left . Type , nativeOperation , true , args ) ;
1925
+ if ( ! found )
1926
+ found = _methodFinder . ContainsMethod ( right . Type , nativeOperation , true , args ) ;
1927
+ }
1928
+
1929
+ if ( ! found && ! _methodFinder . ContainsMethod ( signatures , "F" , false , args ) )
1905
1930
{
1906
1931
throw IncompatibleOperandsError ( opName , left , right , errorPos ) ;
1907
1932
}
0 commit comments