From 7f5d9230c52e62801d5be41b5fc57c1d9e8aa430 Mon Sep 17 00:00:00 2001 From: Bart De Smet Date: Fri, 9 Oct 2015 15:43:59 -0700 Subject: [PATCH 1/2] Fixing interpreter for Increment and Decrement nodes. --- .../Expressions/Interpreter/TypeOperations.cs | 68 ++++++++++++++----- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/TypeOperations.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/TypeOperations.cs index edbb6c2e1905..5cbd9bc0aa78 100644 --- a/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/TypeOperations.cs +++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/TypeOperations.cs @@ -723,7 +723,7 @@ public override string ToString() internal abstract class IncrementInstruction : Instruction { - private static Instruction s_int16, s_int32, s_int64, s_UInt16, s_UInt32, s_single, s_double; + private static Instruction s_int16, s_int32, s_int64, s_UInt16, s_UInt32, s_UInt64, s_single, s_double; public override int ConsumedStack { get { return 1; } } public override int ProducedStack { get { return 1; } } @@ -763,7 +763,7 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push((Int16)unchecked(1 + (Int16)obj)); + frame.Push(unchecked((Int16)(1 + (Int16)obj))); } return +1; } @@ -780,7 +780,7 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push((Int64)unchecked(1 + (Int64)obj)); + frame.Push(unchecked((Int64)(1 + (Int64)obj))); } return +1; } @@ -797,7 +797,7 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push((Int16)unchecked(1 + (UInt16)obj)); + frame.Push(unchecked((UInt16)(1 + (UInt16)obj))); } return +1; } @@ -814,7 +814,24 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push((Int32)unchecked(1 + (UInt32)obj)); + frame.Push(unchecked((UInt32)(1 + (UInt32)obj))); + } + return +1; + } + } + + internal sealed class IncrementUInt64 : IncrementInstruction + { + public override int Run(InterpretedFrame frame) + { + object obj = frame.Pop(); + if (obj == null) + { + frame.Push(null); + } + else + { + frame.Push(unchecked((UInt64)(1 + (UInt64)obj))); } return +1; } @@ -831,7 +848,7 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push((Single)unchecked(1 + (Single)obj)); + frame.Push(unchecked((Single)(1 + (Single)obj))); } return +1; } @@ -848,7 +865,7 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push((Double)unchecked(1 + (Double)obj)); + frame.Push(unchecked((Double)(1 + (Double)obj))); } return +1; } @@ -857,13 +874,14 @@ public override int Run(InterpretedFrame frame) public static Instruction Create(Type type) { Debug.Assert(!type.GetTypeInfo().IsEnum); - switch (System.Dynamic.Utils.TypeExtensions.GetTypeCode(type)) + switch (System.Dynamic.Utils.TypeExtensions.GetTypeCode(TypeUtils.GetNonNullableType(type))) { case TypeCode.Int16: return s_int16 ?? (s_int16 = new IncrementInt16()); case TypeCode.Int32: return s_int32 ?? (s_int32 = new IncrementInt32()); case TypeCode.Int64: return s_int64 ?? (s_int64 = new IncrementInt64()); case TypeCode.UInt16: return s_UInt16 ?? (s_UInt16 = new IncrementUInt16()); case TypeCode.UInt32: return s_UInt32 ?? (s_UInt32 = new IncrementUInt32()); + case TypeCode.UInt64: return s_UInt64 ?? (s_UInt64 = new IncrementUInt64()); case TypeCode.Single: return s_single ?? (s_single = new IncrementSingle()); case TypeCode.Double: return s_double ?? (s_double = new IncrementDouble()); @@ -880,7 +898,7 @@ public override string ToString() internal abstract class DecrementInstruction : Instruction { - private static Instruction s_int16, s_int32, s_int64, s_UInt16, s_UInt32, s_single, s_double; + private static Instruction s_int16, s_int32, s_int64, s_UInt16, s_UInt32, s_UInt64, s_single, s_double; public override int ConsumedStack { get { return 1; } } public override int ProducedStack { get { return 1; } } @@ -920,7 +938,7 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push((Int16)unchecked((Int16)obj - 1)); + frame.Push(unchecked((Int16)((Int16)obj - 1))); } return +1; } @@ -937,7 +955,7 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push((Int64)unchecked((Int64)obj - 1)); + frame.Push(unchecked((Int64)((Int64)obj - 1))); } return +1; } @@ -954,7 +972,7 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push((Int16)unchecked((UInt16)obj - 1)); + frame.Push(unchecked((UInt16)((UInt16)obj - 1))); } return +1; } @@ -971,7 +989,24 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push(unchecked((UInt32)obj - 1)); + frame.Push(unchecked((UInt32)((UInt32)obj - 1))); + } + return +1; + } + } + + internal sealed class DecrementUInt64 : DecrementInstruction + { + public override int Run(InterpretedFrame frame) + { + object obj = frame.Pop(); + if (obj == null) + { + frame.Push(null); + } + else + { + frame.Push(unchecked((UInt64)((UInt64)obj - 1))); } return +1; } @@ -988,7 +1023,7 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push(unchecked((Single)obj - 1)); + frame.Push(unchecked((Single)((Single)obj - 1))); } return +1; } @@ -1005,7 +1040,7 @@ public override int Run(InterpretedFrame frame) } else { - frame.Push((Double)unchecked((Double)obj - 1)); + frame.Push(unchecked((Double)((Double)obj - 1))); } return +1; } @@ -1014,13 +1049,14 @@ public override int Run(InterpretedFrame frame) public static Instruction Create(Type type) { Debug.Assert(!type.GetTypeInfo().IsEnum); - switch (System.Dynamic.Utils.TypeExtensions.GetTypeCode(type)) + switch (System.Dynamic.Utils.TypeExtensions.GetTypeCode(TypeUtils.GetNonNullableType(type))) { case TypeCode.Int16: return s_int16 ?? (s_int16 = new DecrementInt16()); case TypeCode.Int32: return s_int32 ?? (s_int32 = new DecrementInt32()); case TypeCode.Int64: return s_int64 ?? (s_int64 = new DecrementInt64()); case TypeCode.UInt16: return s_UInt16 ?? (s_UInt16 = new DecrementUInt16()); case TypeCode.UInt32: return s_UInt32 ?? (s_UInt32 = new DecrementUInt32()); + case TypeCode.UInt64: return s_UInt64 ?? (s_UInt64 = new DecrementUInt64()); case TypeCode.Single: return s_single ?? (s_single = new DecrementSingle()); case TypeCode.Double: return s_double ?? (s_double = new DecrementDouble()); From b76db20fff136580c37139741718421216894d4e Mon Sep 17 00:00:00 2001 From: Bart De Smet Date: Fri, 9 Oct 2015 16:14:08 -0700 Subject: [PATCH 2/2] Adding tests for Increment and Decrement nodes. --- .../System.Linq.Expressions.Tests.csproj | 6 +- .../Unary/UnaryDecrementNullableTests.cs | 181 ++++++++++++++++++ .../tests/Unary/UnaryDecrementTests.cs | 181 ++++++++++++++++++ .../Unary/UnaryIncrementNullableTests.cs | 181 ++++++++++++++++++ .../tests/Unary/UnaryIncrementTests.cs | 181 ++++++++++++++++++ 5 files changed, 729 insertions(+), 1 deletion(-) create mode 100644 src/System.Linq.Expressions/tests/Unary/UnaryDecrementNullableTests.cs create mode 100644 src/System.Linq.Expressions/tests/Unary/UnaryDecrementTests.cs create mode 100644 src/System.Linq.Expressions/tests/Unary/UnaryIncrementNullableTests.cs create mode 100644 src/System.Linq.Expressions/tests/Unary/UnaryIncrementTests.cs diff --git a/src/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj b/src/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj index fd7a767beba4..e39866d947bd 100644 --- a/src/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj +++ b/src/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj @@ -137,6 +137,10 @@ + + + + @@ -154,4 +158,4 @@ - \ No newline at end of file + diff --git a/src/System.Linq.Expressions/tests/Unary/UnaryDecrementNullableTests.cs b/src/System.Linq.Expressions/tests/Unary/UnaryDecrementNullableTests.cs new file mode 100644 index 000000000000..0a7cb485e578 --- /dev/null +++ b/src/System.Linq.Expressions/tests/Unary/UnaryDecrementNullableTests.cs @@ -0,0 +1,181 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using System.Linq.Expressions; +using Xunit; + +namespace Tests.ExpressionCompiler.Unary +{ + public static unsafe class UnaryDecrementNullableTests + { + #region Test methods + + [Fact] + public static void CheckUnaryDecrementNullableShortTest() + { + short?[] values = new short?[] { null, 0, 1, -1, short.MinValue, short.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementNullableShort(values[i]); + } + } + + [Fact] + public static void CheckUnaryDecrementNullableUShortTest() + { + ushort?[] values = new ushort?[] { null, 0, 1, ushort.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementNullableUShort(values[i]); + } + } + + [Fact] + public static void CheckUnaryDecrementNullableIntTest() + { + int?[] values = new int?[] { null, 0, 1, -1, int.MinValue, int.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementNullableInt(values[i]); + } + } + + [Fact] + public static void CheckUnaryDecrementNullableUIntTest() + { + uint?[] values = new uint?[] { null, 0, 1, uint.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementNullableUInt(values[i]); + } + } + + [Fact] + public static void CheckUnaryDecrementNullableLongTest() + { + long?[] values = new long?[] { null, 0, 1, -1, long.MinValue, long.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementNullableLong(values[i]); + } + } + + [Fact] + public static void CheckUnaryDecrementNullableULongTest() + { + ulong?[] values = new ulong?[] { null, 0, 1, ulong.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementNullableULong(values[i]); + } + } + + [Fact] + public static void CheckDecrementFloatTest() + { + float?[] values = new float?[] { null, 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementNullableFloat(values[i]); + } + } + + [Fact] + public static void CheckDecrementDoubleTest() + { + double?[] values = new double?[] { null, 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementNullableDouble(values[i]); + } + } + + #endregion + + #region Test verifiers + + private static void VerifyDecrementNullableShort(short? value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(short?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((short?)(--value), f()); + } + + private static void VerifyDecrementNullableUShort(ushort? value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(ushort?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((ushort?)(--value), f()); + } + + private static void VerifyDecrementNullableInt(int? value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(int?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((int?)(--value), f()); + } + + private static void VerifyDecrementNullableUInt(uint? value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(uint?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((uint?)(--value), f()); + } + + private static void VerifyDecrementNullableLong(long? value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(long?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((long?)(--value), f()); + } + + private static void VerifyDecrementNullableULong(ulong? value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(ulong?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((ulong?)(--value), f()); + } + + private static void VerifyDecrementNullableFloat(float? value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(float?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((float?)(--value), f()); + } + + private static void VerifyDecrementNullableDouble(double? value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(double?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((double?)(--value), f()); + } + + #endregion + } +} diff --git a/src/System.Linq.Expressions/tests/Unary/UnaryDecrementTests.cs b/src/System.Linq.Expressions/tests/Unary/UnaryDecrementTests.cs new file mode 100644 index 000000000000..afec1168d937 --- /dev/null +++ b/src/System.Linq.Expressions/tests/Unary/UnaryDecrementTests.cs @@ -0,0 +1,181 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using System.Linq.Expressions; +using Xunit; + +namespace Tests.ExpressionCompiler.Unary +{ + public static unsafe class UnaryDecrementTests + { + #region Test methods + + [Fact] + public static void CheckUnaryDecrementShortTest() + { + short[] values = new short[] { 0, 1, -1, short.MinValue, short.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementShort(values[i]); + } + } + + [Fact] + public static void CheckUnaryDecrementUShortTest() + { + ushort[] values = new ushort[] { 0, 1, ushort.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementUShort(values[i]); + } + } + + [Fact] + public static void CheckUnaryDecrementIntTest() + { + int[] values = new int[] { 0, 1, -1, int.MinValue, int.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementInt(values[i]); + } + } + + [Fact] + public static void CheckUnaryDecrementUIntTest() + { + uint[] values = new uint[] { 0, 1, uint.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementUInt(values[i]); + } + } + + [Fact] + public static void CheckUnaryDecrementLongTest() + { + long[] values = new long[] { 0, 1, -1, long.MinValue, long.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementLong(values[i]); + } + } + + [Fact] + public static void CheckUnaryDecrementULongTest() + { + ulong[] values = new ulong[] { 0, 1, ulong.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementULong(values[i]); + } + } + + [Fact] + public static void CheckDecrementFloatTest() + { + float[] values = new float[] { 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementFloat(values[i]); + } + } + + [Fact] + public static void CheckDecrementDoubleTest() + { + double[] values = new double[] { 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }; + for (int i = 0; i < values.Length; i++) + { + VerifyDecrementDouble(values[i]); + } + } + + #endregion + + #region Test verifiers + + private static void VerifyDecrementShort(short value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(short))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((short)(--value), f()); + } + + private static void VerifyDecrementUShort(ushort value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(ushort))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((ushort)(--value), f()); + } + + private static void VerifyDecrementInt(int value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(int))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((int)(--value), f()); + } + + private static void VerifyDecrementUInt(uint value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(uint))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((uint)(--value), f()); + } + + private static void VerifyDecrementLong(long value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(long))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((long)(--value), f()); + } + + private static void VerifyDecrementULong(ulong value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(ulong))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((ulong)(--value), f()); + } + + private static void VerifyDecrementFloat(float value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(float))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((float)(--value), f()); + } + + private static void VerifyDecrementDouble(double value) + { + Expression> e = + Expression.Lambda>( + Expression.Decrement(Expression.Constant(value, typeof(double))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((double)(--value), f()); + } + + #endregion + } +} diff --git a/src/System.Linq.Expressions/tests/Unary/UnaryIncrementNullableTests.cs b/src/System.Linq.Expressions/tests/Unary/UnaryIncrementNullableTests.cs new file mode 100644 index 000000000000..09d23e9cd29e --- /dev/null +++ b/src/System.Linq.Expressions/tests/Unary/UnaryIncrementNullableTests.cs @@ -0,0 +1,181 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using System.Linq.Expressions; +using Xunit; + +namespace Tests.ExpressionCompiler.Unary +{ + public static unsafe class UnaryIncrementNullableTests + { + #region Test methods + + [Fact] + public static void CheckUnaryIncrementNullableShortTest() + { + short?[] values = new short?[] { null, 0, 1, -1, short.MinValue, short.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementNullableShort(values[i]); + } + } + + [Fact] + public static void CheckUnaryIncrementNullableUShortTest() + { + ushort?[] values = new ushort?[] { null, 0, 1, ushort.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementNullableUShort(values[i]); + } + } + + [Fact] + public static void CheckUnaryIncrementNullableIntTest() + { + int?[] values = new int?[] { null, 0, 1, -1, int.MinValue, int.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementNullableInt(values[i]); + } + } + + [Fact] + public static void CheckUnaryIncrementNullableUIntTest() + { + uint?[] values = new uint?[] { null, 0, 1, uint.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementNullableUInt(values[i]); + } + } + + [Fact] + public static void CheckUnaryIncrementNullableLongTest() + { + long?[] values = new long?[] { null, 0, 1, -1, long.MinValue, long.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementNullableLong(values[i]); + } + } + + [Fact] + public static void CheckUnaryIncrementNullableULongTest() + { + ulong?[] values = new ulong?[] { null, 0, 1, ulong.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementNullableULong(values[i]); + } + } + + [Fact] + public static void CheckIncrementFloatTest() + { + float?[] values = new float?[] { null, 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementNullableFloat(values[i]); + } + } + + [Fact] + public static void CheckIncrementDoubleTest() + { + double?[] values = new double?[] { null, 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementNullableDouble(values[i]); + } + } + + #endregion + + #region Test verifiers + + private static void VerifyIncrementNullableShort(short? value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(short?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((short?)(++value), f()); + } + + private static void VerifyIncrementNullableUShort(ushort? value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(ushort?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((ushort?)(++value), f()); + } + + private static void VerifyIncrementNullableInt(int? value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(int?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((int?)(++value), f()); + } + + private static void VerifyIncrementNullableUInt(uint? value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(uint?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((uint?)(++value), f()); + } + + private static void VerifyIncrementNullableLong(long? value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(long?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((long?)(++value), f()); + } + + private static void VerifyIncrementNullableULong(ulong? value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(ulong?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((ulong?)(++value), f()); + } + + private static void VerifyIncrementNullableFloat(float? value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(float?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((float?)(++value), f()); + } + + private static void VerifyIncrementNullableDouble(double? value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(double?))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((double?)(++value), f()); + } + + #endregion + } +} diff --git a/src/System.Linq.Expressions/tests/Unary/UnaryIncrementTests.cs b/src/System.Linq.Expressions/tests/Unary/UnaryIncrementTests.cs new file mode 100644 index 000000000000..2d0dddf92fde --- /dev/null +++ b/src/System.Linq.Expressions/tests/Unary/UnaryIncrementTests.cs @@ -0,0 +1,181 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using System.Linq.Expressions; +using Xunit; + +namespace Tests.ExpressionCompiler.Unary +{ + public static unsafe class UnaryIncrementTests + { + #region Test methods + + [Fact] + public static void CheckUnaryIncrementShortTest() + { + short[] values = new short[] { 0, 1, -1, short.MinValue, short.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementShort(values[i]); + } + } + + [Fact] + public static void CheckUnaryIncrementUShortTest() + { + ushort[] values = new ushort[] { 0, 1, ushort.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementUShort(values[i]); + } + } + + [Fact] + public static void CheckUnaryIncrementIntTest() + { + int[] values = new int[] { 0, 1, -1, int.MinValue, int.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementInt(values[i]); + } + } + + [Fact] + public static void CheckUnaryIncrementUIntTest() + { + uint[] values = new uint[] { 0, 1, uint.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementUInt(values[i]); + } + } + + [Fact] + public static void CheckUnaryIncrementLongTest() + { + long[] values = new long[] { 0, 1, -1, long.MinValue, long.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementLong(values[i]); + } + } + + [Fact] + public static void CheckUnaryIncrementULongTest() + { + ulong[] values = new ulong[] { 0, 1, ulong.MaxValue }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementULong(values[i]); + } + } + + [Fact] + public static void CheckIncrementFloatTest() + { + float[] values = new float[] { 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementFloat(values[i]); + } + } + + [Fact] + public static void CheckIncrementDoubleTest() + { + double[] values = new double[] { 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }; + for (int i = 0; i < values.Length; i++) + { + VerifyIncrementDouble(values[i]); + } + } + + #endregion + + #region Test verifiers + + private static void VerifyIncrementShort(short value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(short))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((short)(++value), f()); + } + + private static void VerifyIncrementUShort(ushort value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(ushort))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((ushort)(++value), f()); + } + + private static void VerifyIncrementInt(int value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(int))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((int)(++value), f()); + } + + private static void VerifyIncrementUInt(uint value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(uint))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((uint)(++value), f()); + } + + private static void VerifyIncrementLong(long value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(long))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((long)(++value), f()); + } + + private static void VerifyIncrementULong(ulong value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(ulong))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((ulong)(++value), f()); + } + + private static void VerifyIncrementFloat(float value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(float))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((float)(++value), f()); + } + + private static void VerifyIncrementDouble(double value) + { + Expression> e = + Expression.Lambda>( + Expression.Increment(Expression.Constant(value, typeof(double))), + Enumerable.Empty()); + Func f = e.Compile(); + Assert.Equal((double)(++value), f()); + } + + #endregion + } +}