diff --git a/src/System.Linq.Dynamic.Core/ExpressionParser.cs b/src/System.Linq.Dynamic.Core/ExpressionParser.cs index f4ec3523..73aa2c39 100644 --- a/src/System.Linq.Dynamic.Core/ExpressionParser.cs +++ b/src/System.Linq.Dynamic.Core/ExpressionParser.cs @@ -17,6 +17,26 @@ interface ILogicalSignatures void F(bool? x, bool? y); } + interface IShiftSignatures + { + void F(int x, int y); + void F(uint x, int y); + void F(long x, int y); + void F(ulong x, int y); + void F(int? x, int y); + void F(uint? x, int y); + void F(long? x, int y); + void F(ulong? x, int y); + void F(int x, int? y); + void F(uint x, int? y); + void F(long x, int? y); + void F(ulong x, int? y); + void F(int? x, int? y); + void F(uint? x, int? y); + void F(long? x, int? y); + void F(ulong? x, int? y); + } + interface IArithmeticSignatures { void F(int x, int y); @@ -739,11 +759,11 @@ Expression ParseShiftOperator() switch (op.Id) { case TokenId.DoubleLessThan: - CheckAndPromoteOperands(typeof(IArithmeticSignatures), op.Text, ref left, ref right, op.Pos); + CheckAndPromoteOperands(typeof(IShiftSignatures), op.Text, ref left, ref right, op.Pos); left = Expression.LeftShift(left, right); break; case TokenId.DoubleGreaterThan: - CheckAndPromoteOperands(typeof(IArithmeticSignatures), op.Text, ref left, ref right, op.Pos); + CheckAndPromoteOperands(typeof(IShiftSignatures), op.Text, ref left, ref right, op.Pos); left = Expression.RightShift(left, right); break; } diff --git a/test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs b/test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs index aeab9fea..46335bdc 100644 --- a/test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs +++ b/test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs @@ -787,20 +787,35 @@ public void ExpressionTests_Select_ExpandoObjects() [Fact] public void ExpressionTests_Shift() + { + ExpressionTests_ShiftInternal(); + ExpressionTests_ShiftInternal(); + ExpressionTests_ShiftInternal(); + ExpressionTests_ShiftInternal(); + ExpressionTests_ShiftInternal(); + ExpressionTests_ShiftInternal(); + ExpressionTests_ShiftInternal(); + ExpressionTests_ShiftInternal(); + } + + private static void ExpressionTests_ShiftInternal() { //Arrange - var lst = new List { 10, 20, 30 }; + var lst = new[] { 10, 20, 30 }.Select(item => (TItemType)Convert.ChangeType(item, typeof(TItemType))); var qry = lst.AsQueryable(); + int? nullableShift = 2; //Act var result1 = qry.Select("it << 1"); var result2 = qry.Select("it >> 1"); var result3 = qry.Where("it << 2 = 80"); + var result4 = qry.Where("it << @0 = 80", nullableShift); //Assert - Assert.Equal(new object[] { 20, 40, 60 }, result1.Cast().ToArray()); - Assert.Equal(new object[] { 5, 10, 15 }, result2.Cast().ToArray()); - Assert.Equal(20, result3.Single()); + Assert.Equal(new[] { 20, 40, 60 }.Select(item => Convert.ChangeType(item, typeof(TResult))).ToArray(), result1.Cast().ToArray()); + Assert.Equal(new[] { 5, 10, 15 }.Select(item => Convert.ChangeType(item, typeof(TResult))).ToArray(), result2.Cast().ToArray()); + Assert.Equal(Convert.ChangeType(20, typeof(TItemType)), result3.Single()); + Assert.Equal(Convert.ChangeType(20, typeof(TItemType)), result4.Single()); } [Fact]