@@ -254,14 +254,16 @@ interface IEnumerableSignatures
254
254
static readonly Expression FalseLiteral = Expression . Constant ( false ) ;
255
255
static readonly Expression NullLiteral = Expression . Constant ( null ) ;
256
256
257
- const string KEYWORD_IT = "it" ;
258
- const string KEYWORD_PARENT = "parent" ;
259
- const string KEYWORD_ROOT = "root" ;
260
257
const string SYMBOL_IT = "$" ;
261
258
const string SYMBOL_PARENT = "^" ;
262
259
const string SYMBOL_ROOT = "~" ;
260
+
261
+ const string KEYWORD_IT = "it" ;
262
+ const string KEYWORD_PARENT = "parent" ;
263
+ const string KEYWORD_ROOT = "root" ;
263
264
const string KEYWORD_IIF = "iif" ;
264
265
const string KEYWORD_NEW = "new" ;
266
+ const string KEYWORD_ISNULL = "isnull" ;
265
267
266
268
static Dictionary < string , object > _keywords ;
267
269
@@ -448,6 +450,18 @@ Expression ParseNullCoalescing()
448
450
return expr ;
449
451
}
450
452
453
+ // isnull(a,b) operator
454
+ Expression ParseIsNull ( )
455
+ {
456
+ int errorPos = _token . pos ;
457
+ NextToken ( ) ;
458
+ Expression [ ] args = ParseArgumentList ( ) ;
459
+ if ( args . Length != 2 )
460
+ throw ParseError ( errorPos , Res . IsNullRequiresTwoArgs ) ;
461
+
462
+ return Expression . Coalesce ( args [ 0 ] , args [ 1 ] ) ;
463
+ }
464
+
451
465
// ||, or operator
452
466
Expression ParseConditionalOr ( )
453
467
{
@@ -1034,6 +1048,7 @@ Expression ParseIdentifier()
1034
1048
if ( value == ( object ) SYMBOL_ROOT ) return ParseRoot ( ) ;
1035
1049
if ( value == ( object ) KEYWORD_IIF ) return ParseIif ( ) ;
1036
1050
if ( value == ( object ) KEYWORD_NEW ) return ParseNew ( ) ;
1051
+ if ( value == ( object ) KEYWORD_ISNULL ) return ParseIsNull ( ) ;
1037
1052
1038
1053
NextToken ( ) ;
1039
1054
@@ -1785,11 +1800,7 @@ Expression PromoteExpression(Expression expr, Type type, bool exact)
1785
1800
{
1786
1801
if ( ce == NullLiteral )
1787
1802
{
1788
- #if ! ( NETFX_CORE || DNXCORE50 || DOTNET5_4 || NETSTANDARD )
1789
1803
if ( ! type . GetTypeInfo ( ) . IsValueType || IsNullableType ( type ) )
1790
- #else
1791
- if ( ! type . GetTypeInfo ( ) . IsValueType || IsNullableType ( type ) )
1792
- #endif
1793
1804
return Expression . Constant ( null , type ) ;
1794
1805
}
1795
1806
else
@@ -1807,6 +1818,10 @@ Expression PromoteExpression(Expression expr, Type type, bool exact)
1807
1818
case TypeCode . Int64 :
1808
1819
case TypeCode . UInt64 :
1809
1820
value = ParseNumber ( text , target ) ;
1821
+
1822
+ // Make sure an enum value stays an enum value
1823
+ if ( target . IsEnum )
1824
+ value = Enum . ToObject ( target , value ) ;
1810
1825
break ;
1811
1826
case TypeCode . Double :
1812
1827
if ( target == typeof ( decimal ) ) value = ParseNumber ( text , target ) ;
@@ -2654,6 +2669,7 @@ static Dictionary<string, object> CreateKeywords()
2654
2669
d . Add ( SYMBOL_ROOT , SYMBOL_ROOT ) ;
2655
2670
d . Add ( KEYWORD_IIF , KEYWORD_IIF ) ;
2656
2671
d . Add ( KEYWORD_NEW , KEYWORD_NEW ) ;
2672
+ d . Add ( KEYWORD_ISNULL , KEYWORD_ISNULL ) ;
2657
2673
2658
2674
foreach ( Type type in _predefinedTypes . OrderBy ( kvp => kvp . Value ) . Select ( kvp => kvp . Key ) )
2659
2675
{
0 commit comments