// Compiler options: -unsafe using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; public struct InverseLogicalOperator { bool value; public InverseLogicalOperator (bool value) { this.value = value; } public static bool operator true (InverseLogicalOperator u) { return u.value; } public static bool operator false (InverseLogicalOperator u) { return u.value; } } /* TODO: Add tests for every numeric expression where a type has only 1 implicit numeric conversion public struct MyType { T value; public MyType (T value) { this.value = value; } public static implicit operator T (MyType o) { return o.value; } } */ // TODO: Create a clone which uses +(MyType, int) pattern and an implicit conversion // is required to do the user-conversion public struct MyType { int value; public MyType (int value) : this () { this.value = value; } public short ShortProp { get; set; } public override int GetHashCode () { throw new NotImplementedException (); } public static implicit operator int (MyType o) { return o.value; } public static bool operator true (MyType a) { return a.value == a; } public static bool operator false (MyType a) { return a.value != a; } public static MyType operator + (MyType a, MyType b) { return new MyType (a.value + b.value); } public static MyType operator - (MyType a, MyType b) { return new MyType (a.value - b.value); } public static MyType operator / (MyType a, MyType b) { return new MyType (a.value / b.value); } public static MyType operator * (MyType a, MyType b) { return new MyType (a.value * b.value); } public static MyType operator % (MyType a, MyType b) { return new MyType (a.value % b.value); } public static MyType operator &(MyType a, MyType b) { return new MyType (a.value & b.value); } public static MyType operator | (MyType a, MyType b) { return new MyType (a.value | b.value); } public static MyType operator ^ (MyType a, MyType b) { return new MyType (a.value ^ b.value); } public static bool operator == (MyType a, MyType b) { return a.value == b.value; } public static bool operator != (MyType a, MyType b) { return a.value != b.value; } public static bool operator > (MyType a, MyType b) { return a.value > b.value; } public static bool operator < (MyType a, MyType b) { return a.value < b.value; } public static bool operator >= (MyType a, MyType b) { return a.value >= b.value; } public static bool operator <= (MyType a, MyType b) { return a.value <= b.value; } public static bool operator ! (MyType a) { return a.value > 0; } public static int operator >> (MyType a, int b) { return a.value >> b; } public static int operator << (MyType a, int b) { return a.value << b; } public static MyType operator - (MyType a) { return new MyType (-a.value); } public static MyType operator + (MyType a) { return new MyType (+a.value); } public override string ToString () { return value.ToString (); } } class MyTypeExplicit { int value; public MyTypeExplicit (int value) { this.value = value; } public static explicit operator int (MyTypeExplicit m) { return m.value; } } struct MyTypeImplicitOnly { short b; public MyTypeImplicitOnly (short b) { this.b = b; } public static implicit operator short (MyTypeImplicitOnly m) { return m.b; } } class MemberAccessData { public bool BoolValue; public static decimal DecimalValue = decimal.MinValue; public volatile uint VolatileValue; public string [] StringValues; public List ListValues; event Func EventField; public Expression>> GetEvent () { return () => EventField; } MyType mt; public MyType MyTypeProperty { set { mt = value; } get { return mt; } } public static string StaticProperty { get { return "alo"; } } public object SetOnly { set { } } } enum MyEnum : byte { Value_1 = 1, Value_2 = 2 } enum MyEnumUlong : ulong { Value_1 = 1 } enum EnumInt { A, B, C } class NewTest { T [] t; public NewTest (T i) { t = new T [] { i }; } public NewTest (params T [] t) { this.t = t; } public override int GetHashCode () { return base.GetHashCode (); } public override bool Equals (object obj) { NewTest obj_t = obj as NewTest; if (obj_t == null) return false; for (int i = 0; i < t.Length; ++i) { if (!t [i].Equals (obj_t.t [i])) return false; } return true; } } class Indexer { public int this [int i] { get { return i; } set { } } public string this [params string[] i] { get { return string.Concat (i); } } } class A { } class B : A { } // TODO: Add more nullable tests, follow AddTest pattern. class Tester { delegate void EmptyDelegate (); delegate int IntDelegate (); static int ReturnNumber () { return 8; } static void AssertNodeType (LambdaExpression e, ExpressionType et) { if (e.Body.NodeType != et) throw new ApplicationException (e.Body.NodeType + " != " + et); } static void Assert (T expected, T value) { Assert (expected, value, null); } static void Assert (T expected, T value, string name) { if (!EqualityComparer.Default.Equals (expected, value)) { if (!string.IsNullOrEmpty (name)) name += ": "; throw new ApplicationException (name + expected + " != " + value); } } static void Assert (T [] expected, T [] value) { if (expected == null) { if (value != null) throw new ApplicationException ("Both arrays expected to be null"); return; } if (expected.Length != value.Length) throw new ApplicationException ("Array length does not match " + expected.Length + " != " + value.Length); for (int i = 0; i < expected.Length; ++i) { if (!EqualityComparer.Default.Equals (expected [i], value [i])) throw new ApplicationException ("Index " + i + ": " + expected [i] + " != " + value [i]); } } #pragma warning disable 169 void AddTest () { Expression> e = (int a, int b) => a + b; AssertNodeType (e, ExpressionType.Add); Assert (50, e.Compile ().Invoke (20, 30)); } void AddTest_2 () { Expression> e2 = (a, b) => a + b; AssertNodeType (e2, ExpressionType.Add); Assert (null, e2.Compile ().Invoke (null, 3)); } void AddTest_3 () { Expression> e3 = (MyType a, MyType b) => a + b; AssertNodeType (e3, ExpressionType.Add); Assert (10, e3.Compile ().Invoke (new MyType (-20), new MyType (30))); } void AddTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a + b; AssertNodeType (e4, ExpressionType.Add); Assert (new MyType (10), e4.Compile ().Invoke (new MyType (-20), new MyType (30))); Assert (null, e4.Compile ().Invoke (null, new MyType (30))); } void AddTest_5 () { Expression> e5 = (int a, MyType b) => a + b; AssertNodeType (e5, ExpressionType.Add); Assert (31, e5.Compile ().Invoke (1, new MyType (30))); } void AddTest_6 () { Expression> e6 = (int a, MyType? b) => a + b; AssertNodeType (e6, ExpressionType.Add); Assert (-1, e6.Compile ().Invoke (-31, new MyType (30))); } void AddTest_7 () { Expression> e7 = (a, b) => a + b; AssertNodeType (e7, ExpressionType.Convert); Assert (MyEnum.Value_2, e7.Compile ().Invoke (MyEnum.Value_1, 1)); } void AddTest_8 () { // CSC BUG: probably due to missing numeric promotion Expression> e8 = (a, b) => a + b; AssertNodeType (e8, ExpressionType.Convert); Assert (0, e8.Compile ().Invoke (MyEnum.Value_1, 255)); Assert (null, e8.Compile ().Invoke (MyEnum.Value_1, null)); Assert (null, e8.Compile ().Invoke (null, null)); } void AddTest_9 () { Expression> e9 = (a, b) => a + b; AssertNodeType (e9, ExpressionType.Convert); Assert (MyEnum.Value_2, e9.Compile ().Invoke (1, MyEnum.Value_1)); } void AddCheckedTest () { checked { Expression> e = (int a, int b) => a + b; AssertNodeType (e, ExpressionType.AddChecked); Assert (50, e.Compile ().Invoke (20, 30)); } } void AddCheckedTest_2 () { checked { Expression> e2 = (a, b) => a + b; AssertNodeType (e2, ExpressionType.AddChecked); Assert (null, e2.Compile ().Invoke (null, 3)); } } void AddCheckedTest_3 () { checked { Expression> e3 = (MyType a, MyType b) => a + b; AssertNodeType (e3, ExpressionType.Add); Assert (10, e3.Compile ().Invoke (new MyType (-20), new MyType (30))); } } void AddStringTest () { Expression> e6 = (a) => 1 + a; AssertNodeType (e6, ExpressionType.Add); Assert ("1to", e6.Compile ().Invoke ("to")); } void AddStringTest_2 () { Expression> e7 = (object a, string b) => a + b; AssertNodeType (e7, ExpressionType.Add); Assert ("testme", e7.Compile ().Invoke ("test", "me")); Assert ("test", e7.Compile ().Invoke ("test", null)); Assert ("", e7.Compile ().Invoke (null, null)); } void AddStringTest_3 () { Expression> e8 = (a, b) => a + " " + "-" + "> " + b; AssertNodeType (e8, ExpressionType.Add); Assert ("test -> 2", e8.Compile ().Invoke ("test", 2)); } void AddStringTest_4 () { Expression> e9 = (a, b) => a + b; AssertNodeType (e9, ExpressionType.Add); Assert ("test2", e9.Compile ().Invoke ("test", 2)); Assert ("test", e9.Compile ().Invoke ("test", null)); } void AndTest () { Expression> e = (bool a, bool b) => a & b; AssertNodeType (e, ExpressionType.And); Func c = e.Compile (); Assert (true, c (true, true)); Assert (false, c (true, false)); Assert (false, c (false, true)); Assert (false, c (false, false)); } void AndTest_2 () { Expression> e2 = (MyType a, MyType b) => a & b; AssertNodeType (e2, ExpressionType.And); var c2 = e2.Compile (); Assert (new MyType (0), c2 (new MyType (0), new MyType (1))); Assert (new MyType (1), c2 (new MyType (0xFF), new MyType (0x01))); } void AndTest_3 () { Expression> e3 = (a, b) => a & b; AssertNodeType (e3, ExpressionType.Convert); Assert (0, e3.Compile ().Invoke (MyEnum.Value_1, MyEnum.Value_2)); Assert (MyEnum.Value_2, e3.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void AndTest_4 () { Expression> e = (a) => a & 0; AssertNodeType (e, ExpressionType.And); var c = e.Compile (); Assert (0, c (1)); } void AndNullableTest () { Expression> e = (bool? a, bool? b) => a & b; AssertNodeType (e, ExpressionType.And); Func c = e.Compile (); Assert (true, c (true, true)); Assert (false, c (true, false)); Assert (false, c (false, true)); Assert (false, c (false, false)); Assert (null, c (true, null)); Assert (false, c (false, null)); Assert (false, c (null, false)); Assert (null, c (true, null)); Assert (null, c (null, null)); } void AndNullableTest_2 () { Expression> e2 = (MyType? a, MyType? b) => a & b; AssertNodeType (e2, ExpressionType.And); var c2 = e2.Compile (); Assert (new MyType (0), c2 (new MyType (0), new MyType (1))); Assert (new MyType (1), c2 (new MyType (0xFF), new MyType (0x01))); Assert (null, c2 (new MyType (0xFF), null)); } void AndNullableTest_3 () { Expression> e3 = (a, b) => a & b; AssertNodeType (e3, ExpressionType.Convert); Assert (null, e3.Compile ().Invoke (null, MyEnum.Value_2)); Assert (MyEnum.Value_2, e3.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void AndAlsoTest () { Expression> e = (bool a, bool b) => a && b; AssertNodeType (e, ExpressionType.AndAlso); Assert (false, e.Compile ().Invoke (true, false)); } void AndAlsoTest_2 () { Expression> e2 = (MyType a, MyType b) => a && b; AssertNodeType (e2, ExpressionType.AndAlso); Assert (new MyType (64), e2.Compile ().Invoke (new MyType (64), new MyType (64))); Assert (new MyType (0), e2.Compile ().Invoke (new MyType (32), new MyType (64))); } void AndAlsoTest_3 () { Expression> e3 = (bool a) => a && true; AssertNodeType (e3, ExpressionType.AndAlso); Assert (false, e3.Compile ().Invoke (false)); Assert (true, e3.Compile ().Invoke (true)); } void ArrayIndexTest () { Expression> e = (string [] a, long i) => a [i]; AssertNodeType (e, ExpressionType.ArrayIndex); Assert ("b", e.Compile ().Invoke (new string [] { "a", "b", "c" }, 1)); } void ArrayIndexTest_2 () { Expression> e2 = (string [] a) => a [0]; AssertNodeType (e2, ExpressionType.ArrayIndex); Assert ("a", e2.Compile ().Invoke (new string [] { "a", "b" })); } void ArrayIndexTest_3 () { Expression> e3 = (object [,] a, int i, int j) => a [i, j]; AssertNodeType (e3, ExpressionType.Call); Assert ("z", e3.Compile ().Invoke ( new object [,] { { 1, 2 }, { "x", "z" } }, 1, 1)); } void ArrayIndexTest_4 () { Expression> e4 = (decimal [] [] a, byte b) => a [b] [1]; AssertNodeType (e4, ExpressionType.ArrayIndex); decimal [] [] array = { new decimal [] { 1, 9 }, new decimal [] { 10, 90 } }; Assert (90, e4.Compile ().Invoke (array, 1)); } void ArrayIndexTest_5 () { Expression> e5 = () => (new int [1]) [0]; AssertNodeType (e5, ExpressionType.ArrayIndex); Assert (0, e5.Compile ().Invoke ()); } void ArrayIndexTest_6 () { const ulong max = 3; Expression> e = a => a [max]; AssertNodeType (e, ExpressionType.ArrayIndex); Assert (4, e.Compile ().Invoke (new int [] { 1, 2, 3, 4, 5 })); } void ArrayIndexTest_7 () { const ulong max = uint.MaxValue; Expression> e = a => a [max]; AssertNodeType (e, ExpressionType.ArrayIndex); try { e.Compile ().Invoke (new int [0]); throw new ApplicationException ("ArrayIndexTest_7"); } catch (System.OverflowException) { // Check whether CheckedConversion was generated } } void ArrayLengthTest () { Expression> e = (double [] a) => a.Length; AssertNodeType (e, ExpressionType.ArrayLength); Assert (0, e.Compile ().Invoke (new double [0])); Assert (9, e.Compile ().Invoke (new double [9])); } void ArrayLengthTest_2 () { Expression> e2 = (string [,] a) => a.Length; AssertNodeType (e2, ExpressionType.MemberAccess); Assert (0, e2.Compile ().Invoke (new string [0, 0])); } void CallTest () { Expression> e = (int a) => Math.Max (a, 5); AssertNodeType (e, ExpressionType.Call); Assert (5, e.Compile ().Invoke (2)); Assert (9, e.Compile ().Invoke (9)); } void CallTest_2 () { Expression> e2 = (string a) => InstanceMethod (a); AssertNodeType (e2, ExpressionType.Call); Assert ("abc", e2.Compile ().Invoke ("abc")); } void CallTest_3 () { Expression> e3 = (int index, string a, int b) => InstanceParamsMethod (index, a, b); AssertNodeType (e3, ExpressionType.Call); Assert (4, e3.Compile ().Invoke (1, "a", 4)); } void CallTest_4 () { Expression> e4 = () => InstanceParamsMethod (0); AssertNodeType (e4, ExpressionType.Call); Assert ("", e4.Compile ().Invoke ()); } void CallTest_5 () { Expression> e5 = (int a) => GenericMethod (a); AssertNodeType (e5, ExpressionType.Call); Assert (5, e5.Compile ().Invoke (5)); } void CallTest_6 () { Expression e6 = () => Console.WriteLine ("call test"); AssertNodeType (e6, ExpressionType.Call); } void CallTest_7 () { Expression> e7 = (a, b) => a [b]; AssertNodeType (e7, ExpressionType.Call); Assert (3, e7.Compile ().Invoke (new Indexer (), 3)); } void CallTest_8 () { Expression> e8 = (a, b, c , d) => a [b, c, d]; AssertNodeType (e8, ExpressionType.Call); Assert ("zyb", e8.Compile ().Invoke (new Indexer (), "z", "y", "b")); } void CallTest_9 () { Expression> e9 = (a) => RefMethod (ref a); AssertNodeType (e9, ExpressionType.Call); e9.Compile ().Invoke (1); } void CallTest_10 () { Expression> e = () => $"{int.MaxValue}"; AssertNodeType (e, ExpressionType.Call); Assert (int.MaxValue.ToString (), e.Compile ().Invoke ()); } void CoalesceTest () { Expression> e = (uint? a) => a ?? 99; AssertNodeType (e, ExpressionType.Coalesce); var r = e.Compile (); Assert ((uint) 5, r.Invoke (5)); Assert ((uint) 99, r.Invoke (null)); } void CoalesceTest_2 () { Expression> e2 = (MyType? a) => a ?? -3; AssertNodeType (e2, ExpressionType.Coalesce); var r2 = e2.Compile (); Assert (2, r2.Invoke (new MyType (2))); Assert (-3, r2.Invoke (null)); } void ConditionTest () { Expression> e = (bool a, byte b, int c) => (a ? b : c); AssertNodeType (e, ExpressionType.Conditional); var r = e.Compile (); Assert (3, r.Invoke (true, 3, 999999)); Assert (999999, r.Invoke (false, 3, 999999)); } void ConditionTest_2 () { Expression> e2 = (int a, decimal d) => (a > 0 ? d : a < 0 ? -d : (decimal?) null); AssertNodeType (e2, ExpressionType.Conditional); var r2 = e2.Compile (); Assert (null, r2.Invoke (0, 10)); Assert (50, r2.Invoke (1, 50)); Assert (30, r2.Invoke (-7, -30)); } void ConditionTest_3 () { Expression> e3 = (bool? a) => ((bool) a ? 3 : -2); AssertNodeType (e3, ExpressionType.Convert); var r3 = e3.Compile (); Assert (3, r3.Invoke (true)); Assert (-2, r3.Invoke (false)); } void ConditionTest_4 () { Expression> e4 = (InverseLogicalOperator a, byte b, byte c) => (a ? b : c); AssertNodeType (e4, ExpressionType.Conditional); var r4 = e4.Compile (); Assert (3, r4.Invoke (new InverseLogicalOperator (true), 3, 4)); Assert (4, r4.Invoke (new InverseLogicalOperator (false), 3, 4)); } void ConditionTest_5 () { // CSC bug ? Expression> e = () => false ? 1 : 4; AssertNodeType (e, ExpressionType.Conditional); var r = e.Compile (); Assert (4, r.Invoke ()); } void ConstantTest () { Expression> e1 = () => default (int); AssertNodeType (e1, ExpressionType.Constant); Assert (0, e1.Compile ().Invoke ()); } void ConstantTest_2 () { Expression> e2 = () => default (int?); AssertNodeType (e2, ExpressionType.Constant); Assert (null, e2.Compile ().Invoke ()); } void ConstantTest_3 () { Expression> e3 = () => default (Tester); AssertNodeType (e3, ExpressionType.Constant); Assert (null, e3.Compile ().Invoke ()); } void ConstantTest_4 () { Expression> e4 = () => null; AssertNodeType (e4, ExpressionType.Constant); Assert (null, e4.Compile ().Invoke ()); } void ConstantTest_5 () { Expression> e5 = () => 8 / 4; AssertNodeType (e5, ExpressionType.Constant); Assert (2, e5.Compile ().Invoke ()); } void ConstantTest_6 () { Expression> e6 = () => 0xFFFFFF >> 0x40; AssertNodeType (e6, ExpressionType.Constant); Assert (0xFFFFFF, e6.Compile ().Invoke ()); } void ConstantTest_7 () { Expression> e7 = () => "Alleluia"; AssertNodeType (e7, ExpressionType.Constant); Assert ("Alleluia", e7.Compile ().Invoke ()); } void ConstantTest_8 () { Expression> e8 = () => typeof (int); AssertNodeType (e8, ExpressionType.Constant); Assert (typeof (int), e8.Compile ().Invoke ()); } void ConstantTest_9 () { Expression> e9 = () => typeof (void); AssertNodeType (e9, ExpressionType.Constant); Assert (typeof (void), e9.Compile ().Invoke ()); } void ConstantTest_10 () { Expression> e10 = () => typeof (Func<,>); AssertNodeType (e10, ExpressionType.Constant); Assert (typeof (Func<,>), e10.Compile ().Invoke ()); } void ConstantTest_11 () { Expression> e11 = () => MyEnum.Value_2; AssertNodeType (e11, ExpressionType.Constant); Assert (MyEnum.Value_2, e11.Compile ().Invoke ()); } void ConstantTest_13 () { Expression> e13 = () => sizeof (byte); AssertNodeType (e13, ExpressionType.Constant); Assert (1, e13.Compile ().Invoke ()); } void ConstantTest_14 () { Expression> e14 = () => typeof (bool*); AssertNodeType (e14, ExpressionType.Constant); Assert (typeof (bool*), e14.Compile ().Invoke ()); } void ConstantTest_15 () { Expression> e15 = () => null; AssertNodeType (e15, ExpressionType.Constant); Assert (null, e15.Compile ().Invoke ()); } void ConvertTest () { Expression> e = (int a) => ((byte) a); AssertNodeType (e, ExpressionType.Convert); Assert (100, e.Compile ().Invoke (100)); } void ConvertTest_2 () { Expression> e2 = (long a) => ((ushort) a); AssertNodeType (e2, ExpressionType.Convert); Assert (100, e2.Compile ().Invoke (100)); } void ConvertTest_3 () { Expression> e3 = (float? a) => ((float) a); AssertNodeType (e3, ExpressionType.Convert); Assert (-0.456f, e3.Compile ().Invoke (-0.456f)); } void ConvertTest_4 () { Expression> e4 = (MyType a) => (a); AssertNodeType (e4, ExpressionType.Convert); Assert (-9, e4.Compile ().Invoke (new MyType (-9))); } void ConvertTest_5 () { Expression> e5 = (MyType a, MyType b) => a == b; AssertNodeType (e5, ExpressionType.Convert); } void ConvertTest_6 () { Expression> e6 = (MyType? a, MyType? b) => a == b; AssertNodeType (e6, ExpressionType.Convert); Assert (false, e6.Compile ().Invoke (null, new MyType (-20))); Assert (true, e6.Compile ().Invoke (null, null)); Assert (true, e6.Compile ().Invoke (new MyType (120), new MyType (120))); } void ConvertTest_7 () { Expression> e7 = x => (int?)x; AssertNodeType (e7, ExpressionType.Convert); Assert (33, e7.Compile ().Invoke (new MyTypeExplicit (33))); } void ConvertTest_8 () { Expression> e8 = x => (object)x; AssertNodeType (e8, ExpressionType.Convert); Assert (null, e8.Compile ().Invoke (null)); Assert (-100, e8.Compile ().Invoke (-100)); } unsafe void ConvertTest_9 () { int*[] p = new int* [1]; Expression> e9 = () => (object)p; AssertNodeType (e9, ExpressionType.Convert); Assert (p, e9.Compile ().Invoke ()); } void ConvertTest_10 () { Expression, Delegate>> e10 = (a) => a + a; AssertNodeType (e10, ExpressionType.Convert); Assert (null, e10.Compile ().Invoke (null)); Assert (new Func (TestInt) + new Func (TestInt), e10.Compile ().Invoke (TestInt)); } void ConvertTest_11 () { Expression, Delegate>> e11 = (a) => a - a; AssertNodeType (e11, ExpressionType.Convert); Assert (null, e11.Compile ().Invoke (null)); } void ConvertTest_12 () { Expression>> e12 = () => TestInt; AssertNodeType (e12, ExpressionType.Convert); Assert (29, e12.Compile ().Invoke () ()); } void ConvertTest_13 () { Expression> e13 = a => (sbyte)a; AssertNodeType (e13, ExpressionType.Convert); Assert (6, e13.Compile ().Invoke (6)); } void ConvertTest_14 () { Expression> e14 = a => a; AssertNodeType (e14, ExpressionType.Convert); Assert (-66, e14.Compile ().Invoke (-66)); } void ConvertTest_15 () { Expression> e15 = a => a; AssertNodeType (e15, ExpressionType.Convert); Assert (null, e15.Compile ().Invoke (null)); Assert (9, e15.Compile ().Invoke (9)); } void ConvertTest_16 () { Expression> e16 = a => (sbyte)a; AssertNodeType (e16, ExpressionType.Convert); Assert (6, e16.Compile ().Invoke (6)); } void ConvertCheckedTest () { Expression> e = (int a) => checked((byte) a); AssertNodeType (e, ExpressionType.ConvertChecked); Assert (100, e.Compile ().Invoke (100)); } void ConvertCheckedTest_2 () { checked { Expression> e2 = (long a) => unchecked((ushort) a); AssertNodeType (e2, ExpressionType.Convert); Assert (100, e2.Compile ().Invoke (100)); } } void ConvertCheckedTest_3 () { checked { Expression> e3 = (float? a) => ((float) a); AssertNodeType (e3, ExpressionType.ConvertChecked); Assert (-0.456f, e3.Compile ().Invoke (-0.456f)); } } void ConvertCheckedTest_4 () { checked { Expression> e4 = (MyType a) => (a); AssertNodeType (e4, ExpressionType.Convert); Assert (-9, e4.Compile ().Invoke (new MyType (-9))); } } void DivideTest () { Expression> e = (int a, int b) => a / b; AssertNodeType (e, ExpressionType.Divide); Assert (2, e.Compile ().Invoke (60, 30)); } void DivideTest_2 () { Expression> e2 = (a, b) => a / b; AssertNodeType (e2, ExpressionType.Divide); Assert (null, e2.Compile ().Invoke (null, 3)); Assert (1.5, e2.Compile ().Invoke (3, 2)); } void DivideTest_3 () { Expression> e3 = (MyType a, MyType b) => a / b; AssertNodeType (e3, ExpressionType.Divide); Assert (1, e3.Compile ().Invoke (new MyType (-20), new MyType (-20))); } void DivideTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a / b; AssertNodeType (e4, ExpressionType.Divide); Assert (null, e4.Compile ().Invoke (null, new MyType (-20))); Assert (new MyType (-6), e4.Compile ().Invoke (new MyType (120), new MyType (-20))); } void DivideTest_5 () { Expression> e5 = (int a, MyType b) => a / b; AssertNodeType (e5, ExpressionType.Divide); Assert (50, e5.Compile ().Invoke (100, new MyType (2))); } void DivideTest_6 () { Expression> e6 = (int a, MyType? b) => a / b; AssertNodeType (e6, ExpressionType.Divide); Assert (50, e6.Compile ().Invoke (100, new MyType (2))); Assert (null, e6.Compile ().Invoke (20, null)); } void DivideTest_7 () { Expression> e = (a, b) => a / b; AssertNodeType (e, ExpressionType.Divide); Assert (50, e.Compile () (100, 2)); Assert (null, e.Compile () (20, null)); } void EqualTest () { Expression> e = (int a, int b) => a == b; AssertNodeType (e, ExpressionType.Equal); Assert (false, e.Compile ().Invoke (60, 30)); Assert (true, e.Compile ().Invoke (-1, -1)); } void EqualTest_2 () { Expression> e2 = (a, b) => a == b; AssertNodeType (e2, ExpressionType.Equal); Assert (true, e2.Compile ().Invoke (3, 3)); Assert (false, e2.Compile ().Invoke (3, 2)); } void EqualTest_3 () { Expression> e3 = (MyType a, MyType b) => a == b; AssertNodeType (e3, ExpressionType.Equal); Assert (true, e3.Compile ().Invoke (new MyType (-20), new MyType (-20))); } void EqualTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a == b; AssertNodeType (e4, ExpressionType.Equal); Assert (false, e4.Compile ().Invoke (null, new MyType (-20))); Assert (true, e4.Compile ().Invoke (null, null)); Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (120))); } void EqualTest_5 () { Expression> e5 = (bool? a, bool? b) => a == b; AssertNodeType (e5, ExpressionType.Equal); Assert (false, e5.Compile ().Invoke (true, null)); Assert (true, e5.Compile ().Invoke (null, null)); Assert (true, e5.Compile ().Invoke (false, false)); } void EqualTest_6 () { Expression> e6 = (bool a) => a == null; AssertNodeType (e6, ExpressionType.Equal); Assert (false, e6.Compile ().Invoke (true)); Assert (false, e6.Compile ().Invoke (false)); } void EqualTest_7 () { Expression> e7 = (string a, string b) => a == b; AssertNodeType (e7, ExpressionType.Equal); Assert (true, e7.Compile ().Invoke (null, null)); Assert (false, e7.Compile ().Invoke ("a", "A")); Assert (true, e7.Compile ().Invoke ("a", "a")); } void EqualTest_8 () { Expression> e8 = (object a) => null == a; AssertNodeType (e8, ExpressionType.Equal); Assert (true, e8.Compile ().Invoke (null)); Assert (false, e8.Compile ().Invoke ("a")); Assert (false, e8.Compile ().Invoke (this)); } void EqualTest_9 () { Expression> e9 = (a, b) => a == b; AssertNodeType (e9, ExpressionType.Equal); Assert (false, e9.Compile ().Invoke (MyEnum.Value_1, MyEnum.Value_2)); Assert (true, e9.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void EqualTest_10 () { Expression> e10 = (a, b) => a == b; AssertNodeType (e10, ExpressionType.Equal); Assert (false, e10.Compile ().Invoke (MyEnum.Value_1, null)); Assert (true, e10.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void EqualTest_11 () { Expression> e11 = (a) => a == null; AssertNodeType (e11, ExpressionType.Equal); Assert (false, e11.Compile ().Invoke (MyEnum.Value_1)); Assert (true, e11.Compile ().Invoke (null)); } void EqualTest_12 () { Expression> e12 = (a) => a == 0; AssertNodeType (e12, ExpressionType.Equal); Assert (false, e12.Compile ().Invoke (MyEnumUlong.Value_1)); Assert (true, e12.Compile ().Invoke (0)); } void EqualTest_13 () { Expression> e13 = (a) => a == MyEnum.Value_2; AssertNodeType (e13, ExpressionType.Equal); Assert (true, e13.Compile ().Invoke (MyEnum.Value_2)); Assert (false, e13.Compile ().Invoke (0)); } void EqualTest_14 () { Expression> e = (a) => a == null; AssertNodeType (e, ExpressionType.Equal); Assert (false, e.Compile ().Invoke (MyEnum.Value_1)); } void EqualTest_15 () { Expression> e = (a, b) => a == b; AssertNodeType (e, ExpressionType.Equal); Assert (false, e.Compile ().Invoke (null, 0)); Assert (true, e.Compile ().Invoke (4, 4)); } void EqualTest_16 () { Expression> e = (x, y) => x == y; AssertNodeType (e, ExpressionType.Convert); Assert (false, e.Compile () (null, 0)); Assert (true, e.Compile () (EnumInt.B, EnumInt.B)); } void EqualTestDelegate () { Expression> e1 = (a, b) => a == b; AssertNodeType (e1, ExpressionType.Equal); Assert (true, e1.Compile ().Invoke (null, null)); } void EqualTestDelegate_2 () { EmptyDelegate ed = delegate () {}; Expression> e2 = (a, b) => a == b; AssertNodeType (e2, ExpressionType.Equal); Assert (false, e2.Compile ().Invoke (delegate () {}, null)); Assert (false, e2.Compile ().Invoke (delegate () {}, delegate {})); Assert (false, e2.Compile ().Invoke (ed, delegate {})); Assert (true, e2.Compile ().Invoke (ed, ed)); } void EqualTestDelegate_3 () { Expression, bool>> e1 = (a) => a == ReturnNumber; AssertNodeType (e1, ExpressionType.Equal); Assert (false, e1.Compile ().Invoke (null)); Assert (true, e1.Compile ().Invoke (ReturnNumber)); } void ExclusiveOrTest () { Expression> e = (int a, short b) => a ^ b; AssertNodeType (e, ExpressionType.ExclusiveOr); Assert (34, e.Compile ().Invoke (60, 30)); } void ExclusiveOrTest_2 () { Expression> e2 = (a, b) => a ^ b; AssertNodeType (e2, ExpressionType.ExclusiveOr); Assert (null, e2.Compile ().Invoke (null, 3)); Assert (1, e2.Compile ().Invoke (3, 2)); } void ExclusiveOrTest_3 () { Expression> e3 = (MyType a, MyType b) => a ^ b; AssertNodeType (e3, ExpressionType.ExclusiveOr); Assert (0, e3.Compile ().Invoke (new MyType (-20), new MyType (-20))); } void ExclusiveOrTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a ^ b; AssertNodeType (e4, ExpressionType.ExclusiveOr); Assert (null, e4.Compile ().Invoke (null, new MyType (-20))); Assert (new MyType (-108), e4.Compile ().Invoke (new MyType (120), new MyType (-20))); } void ExclusiveOrTest_5 () { Expression> e5 = (MyType? a, byte b) => a ^ b; AssertNodeType (e5, ExpressionType.ExclusiveOr); Assert (null, e5.Compile ().Invoke (null, 64)); Assert (96, e5.Compile ().Invoke (new MyType (64), 32)); } void ExclusiveOrTest_6 () { Expression> e6 = (a, b) => a ^ b; AssertNodeType (e6, ExpressionType.Convert); Assert ((MyEnum)3, e6.Compile ().Invoke (MyEnum.Value_1, MyEnum.Value_2)); Assert (0, e6.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void ExclusiveOrTest_7 () { Expression> e7 = (a, b) => a ^ b; AssertNodeType (e7, ExpressionType.Convert); Assert (null, e7.Compile ().Invoke (MyEnum.Value_1, null)); Assert (0, e7.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void ExclusiveOrTest_8 () { Expression> e8 = (a) => a ^ null; AssertNodeType (e8, ExpressionType.Convert); Assert (null, e8.Compile ().Invoke (MyEnum.Value_1)); Assert (null, e8.Compile ().Invoke (null)); } void GreaterThanTest () { Expression> e = (int a, int b) => a > b; AssertNodeType (e, ExpressionType.GreaterThan); Assert (true, e.Compile ().Invoke (60, 30)); } void GreaterThanTest_2 () { Expression> e2 = (a, b) => a > b; AssertNodeType (e2, ExpressionType.GreaterThan); Assert (false, e2.Compile ().Invoke (null, 3)); Assert (false, e2.Compile ().Invoke (2, 2)); } void GreaterThanTest_3 () { Expression> e3 = (MyType a, MyType b) => a > b; AssertNodeType (e3, ExpressionType.GreaterThan); Assert (false, e3.Compile ().Invoke (new MyType (-20), new MyType (-20))); } void GreaterThanTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a > b; AssertNodeType (e4, ExpressionType.GreaterThan); Assert (false, e4.Compile ().Invoke (null, new MyType (-20))); Assert (false, e4.Compile ().Invoke (null, null)); Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (-20))); } void GreaterThanTest_5 () { Expression> e5 = (MyType? a, sbyte b) => a > b; AssertNodeType (e5, ExpressionType.GreaterThan); Assert (false, e5.Compile ().Invoke (null, 33)); Assert (false, e5.Compile ().Invoke (null, 0)); Assert (true, e5.Compile ().Invoke (new MyType (120), 3)); } void GreaterThanTest_6 () { Expression> e6 = (ushort a) => a > null; AssertNodeType (e6, ExpressionType.GreaterThan); Assert (false, e6.Compile ().Invoke (60)); } void GreaterThanTest_7 () { Expression> e7 = (a, b) => a > b; AssertNodeType (e7, ExpressionType.GreaterThan); Assert (true, e7.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_1)); Assert (false, e7.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void GreaterThanTest_8 () { Expression> e8 = (a, b) => a > b; AssertNodeType (e8, ExpressionType.GreaterThan); Assert (false, e8.Compile ().Invoke (MyEnum.Value_1, null)); Assert (false, e8.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void GreaterThanOrEqualTest () { Expression> e = (int a, int b) => a >= b; AssertNodeType (e, ExpressionType.GreaterThanOrEqual); Assert (true, e.Compile ().Invoke (60, 30)); } void GreaterThanOrEqualTest_2 () { Expression> e2 = (a, b) => a >= b; AssertNodeType (e2, ExpressionType.GreaterThanOrEqual); Assert (false, e2.Compile ().Invoke (null, 3)); Assert (true, e2.Compile ().Invoke (2, 2)); } void GreaterThanOrEqualTest_3 () { Expression> e3 = (MyType a, MyType b) => a >= b; AssertNodeType (e3, ExpressionType.GreaterThanOrEqual); Assert (true, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)), "D1"); } void GreaterThanOrEqualTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a >= b; AssertNodeType (e4, ExpressionType.GreaterThanOrEqual); Assert (false, e4.Compile ().Invoke (null, new MyType (-20))); Assert (false, e4.Compile ().Invoke (null, null)); Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (-20))); } void GreaterThanOrEqualTest_5 () { Expression> e5 = (MyType? a, sbyte b) => a >= b; AssertNodeType (e5, ExpressionType.GreaterThanOrEqual); Assert (false, e5.Compile ().Invoke (null, 33)); Assert (false, e5.Compile ().Invoke (null, 0)); Assert (true, e5.Compile ().Invoke (new MyType (120), 3)); } void GreaterThanOrEqualTest_6 () { Expression> e6 = (ushort a) => a >= null; AssertNodeType (e6, ExpressionType.GreaterThanOrEqual); Assert (false, e6.Compile ().Invoke (60)); } void GreaterThanOrEqualTest_7 () { Expression> e7 = (a, b) => a >= b; AssertNodeType (e7, ExpressionType.GreaterThanOrEqual); Assert (true, e7.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_1)); Assert (true, e7.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void GreaterThanOrEqualTest_8 () { Expression> e8 = (a, b) => a >= b; AssertNodeType (e8, ExpressionType.GreaterThanOrEqual); Assert (false, e8.Compile ().Invoke (MyEnum.Value_1, null)); Assert (true, e8.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void InvokeTest () { var del = new IntDelegate (TestInt); Expression> e = (a) => a (); AssertNodeType (e, ExpressionType.Invoke); Assert (29, e.Compile ().Invoke (del)); } void InvokeTest_2 () { Expression, int, string>> e2 = (a, b) => a (b); AssertNodeType (e2, ExpressionType.Invoke); Assert ("4", e2.Compile ().Invoke ((a) => (a+1).ToString (), 3)); } void LambdaTest () { Expression>> e = (string s) => () => s; AssertNodeType (e, ExpressionType.Lambda); Assert ("xx", e.Compile ().Invoke ("xx") ()); } void LeftShiftTest () { Expression> e = (ulong a, short b) => a << b; AssertNodeType (e, ExpressionType.LeftShift); Assert ((ulong) 0x7F000, e.Compile ().Invoke (0xFE, 11)); Assert ((ulong) 0x1FFFFFFFE, e.Compile ().Invoke (0xFFFFFFFF, 0xA01)); // .net produces a strange result // see https://bugzilla.novell.com/show_bug.cgi?id=398358 // Assert ((ulong) 0xFFFFFFFE00000000, e.Compile ().Invoke (0xFFFFFFFF, 0xA01)); } void LeftShiftTest_2 () { Expression> e2 = (MyType a, MyType b) => a << b; AssertNodeType (e2, ExpressionType.LeftShift); var c2 = e2.Compile (); Assert (1024, c2 (new MyType (256), new MyType (2))); } void LeftShiftTest_3 () { Expression> e3 = (long? a, sbyte b) => a << b; AssertNodeType (e3, ExpressionType.LeftShift); Assert (null, e3.Compile ().Invoke (null, 11)); Assert (2048, e3.Compile ().Invoke (1024, 1)); } void LeftShiftTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a << b; AssertNodeType (e4, ExpressionType.LeftShift); var c4 = e4.Compile (); Assert (null, c4 (new MyType (8), null)); Assert (null, c4 (null, new MyType (8))); Assert (1024, c4 (new MyType (256), new MyType (2))); } void LeftShiftTest_5 () { Expression> e5 = (ushort a) => a << null; AssertNodeType (e5, ExpressionType.LeftShift); Assert (null, e5.Compile ().Invoke (30)); } void LeftShiftTest_6 () { Expression> e = (a, b) => a << b; AssertNodeType (e, ExpressionType.LeftShift); Assert (0x7F0, e.Compile ().Invoke (0xFE, new MyTypeImplicitOnly (3))); } void LessThanTest () { Expression> e = (int a, int b) => a < b; AssertNodeType (e, ExpressionType.LessThan); Assert (false, e.Compile ().Invoke (60, 30)); } void LessThanTest_2 () { Expression> e2 = (a, b) => a < b; AssertNodeType (e2, ExpressionType.LessThan); Assert (false, e2.Compile ().Invoke (null, 3)); Assert (false, e2.Compile ().Invoke (2, 2)); } void LessThanTest_3 () { Expression> e3 = (MyType a, MyType b) => a < b; AssertNodeType (e3, ExpressionType.LessThan); Assert (false, e3.Compile ().Invoke (new MyType (-20), new MyType (-20))); } void LessThanTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a < b; AssertNodeType (e4, ExpressionType.LessThan); Assert (false, e4.Compile ().Invoke (null, new MyType (-20))); Assert (false, e4.Compile ().Invoke (null, null)); Assert (false, e4.Compile ().Invoke (new MyType (120), new MyType (-20))); } void LessThanTest_5 () { Expression> e5 = (MyType? a, sbyte b) => a < b; AssertNodeType (e5, ExpressionType.LessThan); Assert (false, e5.Compile ().Invoke (null, 33)); Assert (false, e5.Compile ().Invoke (null, 0)); Assert (false, e5.Compile ().Invoke (new MyType (120), 3)); } void LessThanTest_6 () { Expression> e6 = (ushort a) => a < null; AssertNodeType (e6, ExpressionType.LessThan); Assert (false, e6.Compile ().Invoke (60)); } void LessThanTest_7 () { Expression> e7 = (a, b) => a < b; AssertNodeType (e7, ExpressionType.LessThan); Assert (false, e7.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_1)); Assert (false, e7.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void LessThanTest_8 () { Expression> e8 = (a, b) => a < b; AssertNodeType (e8, ExpressionType.LessThan); Assert (false, e8.Compile ().Invoke (MyEnum.Value_1, null)); Assert (false, e8.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void LessThanTest_9 () { Expression> e = (a, b) => (int) a < b; AssertNodeType (e, ExpressionType.LessThan); Assert (false, e.Compile ().Invoke (1, null)); Assert (false, e.Compile ().Invoke (3, 3)); Assert (true, e.Compile ().Invoke (1, 3)); } void LessThanOrEqualTest () { Expression> e = (int a, int b) => a <= b; AssertNodeType (e, ExpressionType.LessThanOrEqual); Assert (false, e.Compile ().Invoke (60, 30)); } void LessThanOrEqualTest_2 () { Expression> e2 = (a, b) => a <= b; AssertNodeType (e2, ExpressionType.LessThanOrEqual); Assert (false, e2.Compile ().Invoke (null, 3)); Assert (true, e2.Compile ().Invoke (2, 2)); } void LessThanOrEqualTest_3 () { Expression> e3 = (MyType a, MyType b) => a <= b; AssertNodeType (e3, ExpressionType.LessThanOrEqual); Assert (true, e3.Compile ().Invoke (new MyType (-20), new MyType (-20))); } void LessThanOrEqualTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a <= b; AssertNodeType (e4, ExpressionType.LessThanOrEqual); Assert (false, e4.Compile ().Invoke (null, new MyType (-20))); Assert (false, e4.Compile ().Invoke (null, null)); Assert (false, e4.Compile ().Invoke (new MyType (120), new MyType (-20))); } void LessThanOrEqualTest_5 () { Expression> e5 = (MyType? a, sbyte b) => a <= b; AssertNodeType (e5, ExpressionType.LessThanOrEqual); Assert (false, e5.Compile ().Invoke (null, 33)); Assert (false, e5.Compile ().Invoke (null, 0)); Assert (false, e5.Compile ().Invoke (new MyType (120), 3)); } void LessThanOrEqualTest_6 () { Expression> e6 = (ushort a) => a <= null; AssertNodeType (e6, ExpressionType.LessThanOrEqual); Assert (false, e6.Compile ().Invoke (60)); } void LessThanOrEqualTest_7 () { Expression> e7 = (a, b) => a <= b; AssertNodeType (e7, ExpressionType.LessThanOrEqual); Assert (false, e7.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_1)); Assert (true, e7.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void LessThanOrEqualTest_8 () { Expression> e8 = (a, b) => a <= b; AssertNodeType (e8, ExpressionType.LessThanOrEqual); Assert (false, e8.Compile ().Invoke (MyEnum.Value_1, null)); Assert (true, e8.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void ListInitTest () { Expression>> e1 = () => new List { "Hello", "", null, "World", 5 }; AssertNodeType (e1, ExpressionType.ListInit); var re1 = e1.Compile ().Invoke (); Assert (null, re1 [2]); Assert ("World", re1 [3]); Assert (5, re1 [4]); } void ListInitTest_2 () { Expression>> e2 = (int value) => new Dictionary (3) { { "A", value }, { "B", 2 } }; AssertNodeType (e2, ExpressionType.ListInit); var re2 = e2.Compile ().Invoke (3456); Assert (3456, re2 ["A"]); } void MemberAccessTest () { MemberAccessData d = new MemberAccessData (); d.BoolValue = true; Expression> e = () => d.BoolValue; AssertNodeType (e, ExpressionType.MemberAccess); Assert (true, e.Compile ().Invoke ()); d.BoolValue = false; Assert (false, e.Compile ().Invoke ()); } void MemberAccessTest_2 () { Expression> e2 = () => MemberAccessData.DecimalValue; AssertNodeType (e2, ExpressionType.MemberAccess); Assert (decimal.MinValue, e2.Compile ().Invoke ()); } void MemberAccessTest_3 () { MemberAccessData d = new MemberAccessData (); d.VolatileValue = 492; Expression> e3 = () => d.VolatileValue; AssertNodeType (e3, ExpressionType.MemberAccess); Assert (492, e3.Compile ().Invoke ()); } void MemberAccessTest_4 () { MemberAccessData d = new MemberAccessData (); Expression> e4 = () => d.StringValues; AssertNodeType (e4, ExpressionType.MemberAccess); Assert (null, e4.Compile ().Invoke ()); } void MemberAccessTest_5 () { MemberAccessData d = new MemberAccessData (); var e5 = d.GetEvent (); AssertNodeType (e5, ExpressionType.MemberAccess); Assert (null, e5.Compile ().Invoke ()); } void MemberAccessTest_6 () { MemberAccessData d = new MemberAccessData (); Expression> e6 = () => d.MyTypeProperty; AssertNodeType (e6, ExpressionType.MemberAccess); Assert (new MyType (), e6.Compile ().Invoke ()); } void MemberAccessTest_7 () { MemberAccessData d = new MemberAccessData (); Expression> e7 = a => a.ShortProp; AssertNodeType (e7, ExpressionType.MemberAccess); MyType mt = new MyType (); mt.ShortProp = 124; Assert (124, e7.Compile ().Invoke (mt)); } void MemberAccessTest_8 () { Expression> e8 = () => MemberAccessData.StaticProperty; AssertNodeType (e8, ExpressionType.MemberAccess); Assert ("alo", e8.Compile ().Invoke ()); } void MemberAccessTest_9 () { string s = "localvar"; Expression> e9 = () => s; s = "changed"; AssertNodeType (e9, ExpressionType.MemberAccess); Assert ("changed", e9.Compile ().Invoke ()); } void MemberInitTest () { Expression> e = () => new MemberAccessData { VolatileValue = 2, StringValues = new string [] { "sv" }, MyTypeProperty = new MyType (692) }; AssertNodeType (e, ExpressionType.MemberInit); var r1 = e.Compile ().Invoke (); Assert (2, r1.VolatileValue); Assert (new string[] { "sv" }, r1.StringValues); Assert (new MyType (692), r1.MyTypeProperty); } void MemberInitTest_2 () { Expression> e2 = () => new MemberAccessData { ListValues = new List { "a", null } }; AssertNodeType (e2, ExpressionType.MemberInit); var r2 = e2.Compile ().Invoke (); Assert ("a", r2.ListValues [0]); } void MemberInitTest_3 () { Expression> e3 = a => new MyType { ShortProp = a }; AssertNodeType (e3, ExpressionType.MemberInit); var r3 = e3.Compile ().Invoke (33); Assert (33, r3.ShortProp); } void MemberInitTest_4 () { Expression> e = () => new int { }; AssertNodeType (e, ExpressionType.MemberInit); var r = e.Compile ().Invoke (); Assert (0, r); } void MemberInitTest_5 () { Expression> e = () => new MemberAccessData { SetOnly = new object { } }; AssertNodeType (e, ExpressionType.MemberInit); e.Compile () (); } void ModuloTest () { Expression> e = (int a, int b) => a % b; AssertNodeType (e, ExpressionType.Modulo); Assert (29, e.Compile ().Invoke (60, 31)); } void ModuloTest_2 () { Expression> e2 = (a, b) => a % b; AssertNodeType (e2, ExpressionType.Modulo); Assert (null, e2.Compile ().Invoke (null, 3)); Assert (1.1, e2.Compile ().Invoke (3.1, 2)); } void ModuloTest_3 () { Expression> e3 = (MyType a, MyType b) => a % b; AssertNodeType (e3, ExpressionType.Modulo); Assert (0, e3.Compile ().Invoke (new MyType (-20), new MyType (-20))); } void ModuloTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a % b; AssertNodeType (e4, ExpressionType.Modulo); Assert (null, e4.Compile ().Invoke (null, new MyType (-20))); Assert (new MyType (12), e4.Compile ().Invoke (new MyType (12), new MyType (-20))); } void ModuloTest_5 () { Expression> e5 = (int a, MyType b) => a % b; AssertNodeType (e5, ExpressionType.Modulo); Assert (1, e5.Compile ().Invoke (99, new MyType (2))); } void ModuloTest_6 () { Expression> e6 = (int a, MyType? b) => a % b; AssertNodeType (e6, ExpressionType.Modulo); Assert (100, e6.Compile ().Invoke (100, new MyType (200))); Assert (null, e6.Compile ().Invoke (20, null)); } void ModuloTest_7 () { Expression> e7 = (ushort a) => a % null; AssertNodeType (e7, ExpressionType.Modulo); Assert (null, e7.Compile ().Invoke (60)); } void MultiplyTest () { Expression> e = (int a, int b) => a * b; AssertNodeType (e, ExpressionType.Multiply); Assert (1860, e.Compile ().Invoke (60, 31)); Assert (2147483617, e.Compile ().Invoke (int.MaxValue, 31)); } void MultiplyTest_2 () { Expression> e2 = (a, b) => a * b; AssertNodeType (e2, ExpressionType.Multiply); Assert (null, e2.Compile ().Invoke (null, 3)); Assert (6.2, e2.Compile ().Invoke (3.1, 2)); } void MultiplyTest_3 () { Expression> e3 = (MyType a, MyType b) => a * b; AssertNodeType (e3, ExpressionType.Multiply); Assert (400, e3.Compile ().Invoke (new MyType (-20), new MyType (-20))); } void MultiplyTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a * b; AssertNodeType (e4, ExpressionType.Multiply); Assert (null, e4.Compile ().Invoke (null, new MyType (-20))); Assert (new MyType (-240), e4.Compile ().Invoke (new MyType (12), new MyType (-20))); } void MultiplyTest_5 () { Expression> e5 = (int a, MyType b) => a * b; AssertNodeType (e5, ExpressionType.Multiply); Assert (198, e5.Compile ().Invoke (99, new MyType (2))); } void MultiplyTest_6 () { Expression> e6 = (int a, MyType? b) => a * b; AssertNodeType (e6, ExpressionType.Multiply); Assert (0, e6.Compile ().Invoke (int.MinValue, new MyType (200))); Assert (null, e6.Compile ().Invoke (20, null)); } void MultiplyTest_7 () { Expression> e7 = (ushort a) => a * null; AssertNodeType (e7, ExpressionType.Multiply); Assert (null, e7.Compile ().Invoke (60)); } void MultiplyTest_8 () { Expression> e = (a, b) => a * b; AssertNodeType (e, ExpressionType.Multiply); Assert (180, e.Compile () (60, 3)); Assert (null, e.Compile () (60, null)); } void MultiplyCheckedTest () { checked { Expression> e = (int a, int b) => a * b; AssertNodeType (e, ExpressionType.MultiplyChecked); try { e.Compile ().Invoke (int.MaxValue, 309); throw new ApplicationException ("MultiplyCheckedTest #1"); } catch (OverflowException) { } } } void MultiplyCheckedTest_2 () { checked { Expression> e2 = (a, b) => a * b; AssertNodeType (e2, ExpressionType.MultiplyChecked); Assert (null, e2.Compile ().Invoke (null, 3)); Assert (14025, e2.Compile ().Invoke (byte.MaxValue, 55)); } } void MultiplyCheckedTest_3 () { checked { Expression> e3 = (MyType a, MyType b) => a * b; AssertNodeType (e3, ExpressionType.Multiply); Assert (-600, e3.Compile ().Invoke (new MyType (-20), new MyType (30))); } } void MultiplyCheckedTest_4 () { checked { Expression> e4 = (a, b) => a * b; AssertNodeType (e4, ExpressionType.Multiply); Assert (double.PositiveInfinity, e4.Compile ().Invoke (double.MaxValue, int.MaxValue)); } } void MultiplyCheckedTest_5 () { checked { Expression> e5 = (a, b) => b * a; AssertNodeType (e5, ExpressionType.MultiplyChecked); Assert (float.PositiveInfinity, e5.Compile ().Invoke (float.Epsilon, float.PositiveInfinity)); } } void NegateTest () { Expression> e = (a) => -a; AssertNodeType (e, ExpressionType.Negate); Assert (30, e.Compile ().Invoke (-30)); } void NegateTest_2 () { Expression> e2 = (a) => -(-a); AssertNodeType (e2, ExpressionType.Negate); Assert (-10, e2.Compile ().Invoke (-10)); } void NegateTest_3 () { Expression> e3 = (a) => -a; AssertNodeType (e3, ExpressionType.Negate); Assert (long.MinValue + 1, e3.Compile ().Invoke (long.MaxValue)); Assert (null, e3.Compile ().Invoke (null)); } void NegateTest_4 () { Expression> e4 = (a) => -a; AssertNodeType (e4, ExpressionType.Negate); Assert (new MyType (14), e4.Compile ().Invoke (new MyType (-14))); } void NegateTest_5 () { Expression> e5 = (a) => -a; AssertNodeType (e5, ExpressionType.Negate); Assert (new MyType (-33), e5.Compile ().Invoke (new MyType (33))); Assert (null, e5.Compile ().Invoke (null)); } void NegateTest_6 () { Expression> e6 = (MyTypeImplicitOnly a) => -a; AssertNodeType (e6, ExpressionType.Negate); Assert (-4, e6.Compile ().Invoke (new MyTypeImplicitOnly (4))); } void NegateTest_7 () { Expression> e7 = (MyTypeImplicitOnly? a) => -a; AssertNodeType (e7, ExpressionType.Negate); Assert (-46, e7.Compile ().Invoke (new MyTypeImplicitOnly (46))); // Another version of MS bug when predefined conversion is required on nullable user operator // Assert (null, e7.Compile ().Invoke (null)); } void NegateTest_8 () { Expression> e8 = (a) => -a; AssertNodeType (e8, ExpressionType.Negate); Assert (11, e8.Compile ().Invoke (-11)); } void NegateTest_9 () { Expression> e9 = (a) => -a; AssertNodeType (e9, ExpressionType.Negate); Assert (-2, e9.Compile ().Invoke (2)); } void NegateTestChecked () { checked { Expression> e = (int a) => -a; AssertNodeType (e, ExpressionType.NegateChecked); try { e.Compile ().Invoke (int.MinValue); throw new ApplicationException ("NegateTestChecked #1"); } catch (OverflowException) { } } } void NegateTestChecked_2 () { checked { Expression> e2 = (a) => -a; AssertNodeType (e2, ExpressionType.NegateChecked); Assert (null, e2.Compile ().Invoke (null)); Assert (-255, e2.Compile ().Invoke (byte.MaxValue)); } } void NegateTestChecked_3 () { checked { Expression> e3 = (MyType a) => -a; AssertNodeType (e3, ExpressionType.Negate); Assert (20, e3.Compile ().Invoke (new MyType (-20))); } } void NegateTestChecked_4 () { checked { Expression> e4 = (a) => -a; AssertNodeType (e4, ExpressionType.Negate); Assert (double.NegativeInfinity, e4.Compile ().Invoke (double.PositiveInfinity)); } } void NewArrayInitTest () { Expression> e = () => new int [1] { 5 }; AssertNodeType (e, ExpressionType.NewArrayInit); Assert (new int [1] { 5 }, e.Compile ().Invoke ()); } void NewArrayInitTest_2 () { Expression> e1 = () => new int [] { }; AssertNodeType (e1, ExpressionType.NewArrayInit); Assert (new int [0], e1.Compile ().Invoke ()); } void NewArrayInitTest_3 () { Expression> e2 = (ushort a) => new ulong? [] { a }; AssertNodeType (e2, ExpressionType.NewArrayInit); Assert (new ulong? [1] { ushort.MaxValue }, e2.Compile ().Invoke (ushort.MaxValue)); } void NewArrayInitTest_4 () { Expression> e3 = () => new char [] [] { new char [] { 'a' } }; AssertNodeType (e3, ExpressionType.NewArrayInit); Assert (new char [] { 'a' }, e3.Compile ().Invoke () [0]); } void NewArrayInitTest_5 () { Expression> e = () => new int?[] { null, 3, 4 }; AssertNodeType (e, ExpressionType.NewArrayInit); Assert (3, e.Compile ().Invoke ().Length); } void NewArrayInitTest_6 () { Expression> e = () => new [] { null, "a" }; AssertNodeType (e, ExpressionType.NewArrayInit); Assert (2, e.Compile ().Invoke ().Length); } void NewArrayBoundsTest () { Expression> e = () => new int [2,3]; AssertNodeType (e, ExpressionType.NewArrayBounds); Assert (new int [2,3].Length, e.Compile ().Invoke ().Length); } void NewArrayBoundsTest_2 () { Expression> e2 = () => new int [0,0]; AssertNodeType (e2, ExpressionType.NewArrayBounds); Assert (new int [0, 0].Length, e2.Compile ().Invoke ().Length); } void NewArrayBoundsTest_3 () { Expression> e = () => new int [0]; AssertNodeType (e, ExpressionType.NewArrayBounds); Assert (0, e.Compile ().Invoke ().Length); } void NewArrayBoundsTest_4 () { const ulong max = ulong.MaxValue; Expression> e = () => new bool [max]; AssertNodeType (e, ExpressionType.NewArrayBounds); } void NewTest () { Expression> e = () => new MyType (2); AssertNodeType (e, ExpressionType.New); Assert (new MyType (2), e.Compile ().Invoke ()); } void NewTest_2 () { Expression> e2 = () => new MyType (); AssertNodeType (e2, ExpressionType.New); Assert (new MyType (), e2.Compile ().Invoke ()); } void NewTest_3 () { Expression>> e3 = () => new NewTest (true); AssertNodeType (e3, ExpressionType.New); Assert (new NewTest (true), e3.Compile ().Invoke ()); } void NewTest_4 () { Expression>> e4 = (decimal d) => new NewTest (1, 5, d); AssertNodeType (e4, ExpressionType.New); Assert (new NewTest (1, 5, -9), e4.Compile ().Invoke (-9)); } void NewTest_5 () { Expression> e5 = () => new { A = 9, Value = "a" }; AssertNodeType (e5, ExpressionType.New); var ne = ((NewExpression) e5.Body); Assert (2, ne.Members.Count, "members count"); // Behaviour is different between .NET 3.5 and .NET 4.0 if (ne.Members [0].MemberType == MemberTypes.Property) { Assert ("A", ne.Members [0].Name, "Name #1"); Assert ("Value", ne.Members [1].Name, "Name #2"); } else { Assert ("get_A", ne.Members [0].Name, "Name #1"); Assert ("get_Value", ne.Members [1].Name, "Name #2"); } Assert (new { A = 9, Value = "a" }, e5.Compile ().Invoke ()); } void NewTest_6 () { Expression> e5 = () => new { A = 9, Value = new MyType (5) }; AssertNodeType (e5, ExpressionType.New); } // CSC bug: emits new MyEnum as a constant void NewTest_7 () { Expression> e = () => new MyEnum (); AssertNodeType (e, ExpressionType.New); Assert (0, e.Compile ().Invoke ()); } void NewTest_8 () { Expression> e = () => new DateTime (); AssertNodeType (e, ExpressionType.New); Assert (null, ((NewExpression)e.Body).Constructor, "default ctor"); } void NotTest () { Expression> e = (bool a) => !a; AssertNodeType (e, ExpressionType.Not); Assert (false, e.Compile ().Invoke (true)); } void NotTest_2 () { Expression> e2 = (MyType a) => !a; AssertNodeType (e2, ExpressionType.Not); Assert (true, e2.Compile ().Invoke (new MyType (1))); Assert (false, e2.Compile ().Invoke (new MyType (-1))); } void NotTest_3 () { Expression> e3 = (int a) => ~a; AssertNodeType (e3, ExpressionType.Not); Assert (-8, e3.Compile ().Invoke (7)); } void NotTest_4 () { Expression> e4 = (MyType a) => ~a; AssertNodeType (e4, ExpressionType.Not); Assert (0, e4.Compile ().Invoke (new MyType (-1))); } void NotTest_5 () { Expression> e5 = (ulong a) => ~a; AssertNodeType (e5, ExpressionType.Not); Assert (18446744073709551608, e5.Compile ().Invoke (7)); } void NotTest_6 () { Expression> e6 = (MyEnum a) => ~a; AssertNodeType (e6, ExpressionType.Convert); Assert ((MyEnum)254, e6.Compile ().Invoke (MyEnum.Value_1)); } void NotNullableTest () { Expression> e = (bool? a) => !a; AssertNodeType (e, ExpressionType.Not); Assert (false, e.Compile ().Invoke (true)); Assert (null, e.Compile ().Invoke (null)); } void NotNullableTest_2 () { Expression> e2 = (MyType? a) => !a; AssertNodeType (e2, ExpressionType.Not); Assert (true, e2.Compile ().Invoke (new MyType (1))); Assert (null, e2.Compile ().Invoke (null)); } void NotNullableTest_3 () { Expression> e3 = (sbyte? a) => ~a; AssertNodeType (e3, ExpressionType.Not); Assert (-5, e3.Compile ().Invoke (4)); Assert (null, e3.Compile ().Invoke (null)); } void NotNullableTest_4 () { Expression> e4 = (MyType? a) => ~a; AssertNodeType (e4, ExpressionType.Not); Assert (0, e4.Compile ().Invoke (new MyType (-1))); Assert (null, e4.Compile ().Invoke (null)); } void NotNullableTest_5 () { Expression> e5 = (MyEnum? a) => ~a; AssertNodeType (e5, ExpressionType.Convert); Assert ((MyEnum) 254, e5.Compile ().Invoke (MyEnum.Value_1)); Assert (null, e5.Compile ().Invoke (null)); } void NotEqualTest () { Expression> e = (int a, int b) => a != b; AssertNodeType (e, ExpressionType.NotEqual); Assert (true, e.Compile ().Invoke (60, 30)); Assert (false, e.Compile ().Invoke (-1, -1)); } void NotEqualTest_2 () { Expression> e2 = (a, b) => a != b; AssertNodeType (e2, ExpressionType.NotEqual); Assert (false, e2.Compile ().Invoke (3, 3)); Assert (true, e2.Compile ().Invoke (3, 2)); } void NotEqualTest_3 () { Expression> e3 = (MyType a, MyType b) => a != b; AssertNodeType (e3, ExpressionType.NotEqual); Assert (false, e3.Compile ().Invoke (new MyType (-20), new MyType (-20))); } void NotEqualTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a != b; AssertNodeType (e4, ExpressionType.NotEqual); Assert (true, e4.Compile ().Invoke (null, new MyType (-20))); Assert (false, e4.Compile ().Invoke (null, null)); Assert (false, e4.Compile ().Invoke (new MyType (120), new MyType (120))); } void NotEqualTest_5 () { Expression> e5 = (bool? a, bool? b) => a != b; AssertNodeType (e5, ExpressionType.NotEqual); Assert (true, e5.Compile ().Invoke (true, null)); Assert (false, e5.Compile ().Invoke (null, null)); Assert (false, e5.Compile ().Invoke (false, false)); } void NotEqualTest_6 () { Expression> e6 = (bool a) => a != null; AssertNodeType (e6, ExpressionType.NotEqual); Assert (true, e6.Compile ().Invoke (true)); Assert (true, e6.Compile ().Invoke (false)); } void NotEqualTest_7 () { Expression> e7 = (string a, string b) => a != b; AssertNodeType (e7, ExpressionType.NotEqual); Assert (false, e7.Compile ().Invoke (null, null)); Assert (true, e7.Compile ().Invoke ("a", "A")); Assert (false, e7.Compile ().Invoke ("a", "a")); } void NotEqualTest_8 () { Expression> e8 = (object a) => null != a; AssertNodeType (e8, ExpressionType.NotEqual); Assert (false, e8.Compile ().Invoke (null)); Assert (true, e8.Compile ().Invoke ("a")); Assert (true, e8.Compile ().Invoke (this)); } void NotEqualTest_9 () { Expression> e9 = (a, b) => a != b; AssertNodeType (e9, ExpressionType.NotEqual); Assert (true, e9.Compile ().Invoke (MyEnum.Value_1, MyEnum.Value_2)); Assert (false, e9.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void NotEqualTest_10 () { Expression> e10 = (a, b) => a != b; AssertNodeType (e10, ExpressionType.NotEqual); Assert (true, e10.Compile ().Invoke (MyEnum.Value_1, null)); Assert (false, e10.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void NotEqualTest_11 () { Expression> e11 = (a) => a != null; AssertNodeType (e11, ExpressionType.NotEqual); Assert (true, e11.Compile ().Invoke (MyEnum.Value_1)); Assert (false, e11.Compile ().Invoke (null)); } void OrTest () { Expression> e = (bool a, bool b) => a | b; AssertNodeType (e, ExpressionType.Or); Func c = e.Compile (); Assert (true, c (true, true)); Assert (true, c (true, false)); Assert (true, c (false, true)); Assert (false, c (false, false)); } void OrTest_2 () { Expression> e2 = (MyType a, MyType b) => a | b; AssertNodeType (e2, ExpressionType.Or); var c2 = e2.Compile (); Assert (new MyType (3), c2 (new MyType (1), new MyType (2))); } void OrTest_3 () { Expression> e3 = (a, b) => a | b; AssertNodeType (e3, ExpressionType.Convert); Assert ((MyEnum)3, e3.Compile ().Invoke (MyEnum.Value_1, MyEnum.Value_2)); Assert (MyEnum.Value_2, e3.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_2)); } void OrNullableTest () { Expression> e = (bool? a, bool? b) => a | b; AssertNodeType (e, ExpressionType.Or); Func c = e.Compile (); Assert (true, c (true, true)); Assert (true, c (true, false)); Assert (true, c (false, true)); Assert (false, c (false, false)); Assert (true, c (true, null)); Assert (null, c (false, null)); Assert (null, c (null, false)); Assert (true, c (true, null)); Assert (null, c (null, null)); } void OrNullableTest_2 () { Expression> e2 = (MyType? a, MyType? b) => a | b; AssertNodeType (e2, ExpressionType.Or); var c2 = e2.Compile (); Assert (new MyType (3), c2 (new MyType (1), new MyType (2))); Assert (null, c2 (new MyType (1), null)); } void OrNullableTest_3 () { Expression> e3 = (MyType? a, uint b) => a | b; AssertNodeType (e3, ExpressionType.Or); var c3 = e3.Compile (); Assert (9, c3 (new MyType (1), 8)); } void OrNullableTest_4 () { Expression> e4 = (a, b) => a | b; AssertNodeType (e4, ExpressionType.Convert); Assert (null, e4.Compile ().Invoke (null, MyEnum.Value_2)); Assert ((MyEnum)3, e4.Compile ().Invoke (MyEnum.Value_1, MyEnum.Value_2)); } void OrElseTest () { Expression> e = (bool a, bool b) => a || b; AssertNodeType (e, ExpressionType.OrElse); Assert (true, e.Compile ().Invoke (true, false)); } void OrElseTest_2 () { Expression> e2 = (MyType a, MyType b) => a || b; AssertNodeType (e2, ExpressionType.OrElse); Assert (new MyType (64), e2.Compile ().Invoke (new MyType (64), new MyType (64))); Assert (new MyType (32), e2.Compile ().Invoke (new MyType (32), new MyType (64))); } void ParameterTest () { Expression> e = (string a) => a; AssertNodeType (e, ExpressionType.Parameter); Assert ("t", e.Compile ().Invoke ("t")); } void ParameterTest_2 () { Expression> e2 = (object[] a) => a; AssertNodeType (e2, ExpressionType.Parameter); Assert (new object [0], e2.Compile ().Invoke (new object [0])); } void ParameterTest_3 () { Expression> e3 = a => a; AssertNodeType (e3, ExpressionType.Parameter); Assert (IntPtr.Zero, e3.Compile ().Invoke (IntPtr.Zero)); } unsafe void ParameterTest_4 () { Expression> e4 = (a) => a; AssertNodeType (e4, ExpressionType.Parameter); Assert (null, e4.Compile ().Invoke (null)); int* e4_el = stackalloc int [5]; int*[] ptr = new int*[] { e4_el }; Assert (ptr, e4.Compile ().Invoke (ptr)); } void QuoteTest () { Expression>>> e = () => () => 2; AssertNodeType (e, ExpressionType.Quote); Assert (2, e.Compile ().Invoke ().Compile ().Invoke ()); } void QuoteTest_2 () { Expression>>> e = (string s) => () => s; AssertNodeType (e, ExpressionType.Quote); Assert ("data", e.Compile ().Invoke ("data").Compile ().Invoke ()); } void RightShiftTest () { Expression> e = (ulong a, short b) => a >> b; AssertNodeType (e, ExpressionType.RightShift); Assert ((ulong) 0x1FD940L, e.Compile ().Invoke (0xFECA0000, 11)); Assert ((ulong) 0x7FFFFFFF, e.Compile ().Invoke (0xFFFFFFFF, 0xA01)); // .net produces a strange result // see https://bugzilla.novell.com/show_bug.cgi?id=398358 // Assert ((ulong)0, e.Compile ().Invoke (0xFFFFFFFF, 0xA01)); } void RightShiftTest_2 () { Expression> e2 = (MyType a, MyType b) => a >> b; AssertNodeType (e2, ExpressionType.RightShift); var c2 = e2.Compile (); Assert (64, c2 (new MyType (256), new MyType (2))); } void RightShiftTest_3 () { Expression> e3 = (long? a, sbyte b) => a >> b; AssertNodeType (e3, ExpressionType.RightShift); Assert (null, e3.Compile ().Invoke (null, 11)); Assert (512, e3.Compile ().Invoke (1024, 1)); } void RightShiftTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a >> b; AssertNodeType (e4, ExpressionType.RightShift); var c4 = e4.Compile (); Assert (null, c4 (new MyType (8), null)); Assert (null, c4 (null, new MyType (8))); Assert (64, c4 (new MyType (256), new MyType (2))); } void RightShiftTest_5 () { Expression> e = (a, b) => a >> b; AssertNodeType (e, ExpressionType.RightShift); Assert (31, e.Compile ().Invoke (0xFE, new MyTypeImplicitOnly (3))); } void RightShiftTest_6 () { Expression> e = (a, b) => a >> b; AssertNodeType (e, ExpressionType.RightShift); Assert (null, e.Compile () (2, null)); } void SubtractTest () { Expression> e = (int a, int b) => a - b; AssertNodeType (e, ExpressionType.Subtract); Assert (-10, e.Compile ().Invoke (20, 30)); } void SubtractTest_2 () { Expression> e2 = (a, b) => a - b; AssertNodeType (e2, ExpressionType.Subtract); Assert (null, e2.Compile ().Invoke (null, 3)); } void SubtractTest_3 () { Expression> e3 = (MyType a, MyType b) => a - b; AssertNodeType (e3, ExpressionType.Subtract); Assert (-50, e3.Compile ().Invoke (new MyType (-20), new MyType (30))); } void SubtractTest_4 () { Expression> e4 = (MyType? a, MyType? b) => a - b; AssertNodeType (e4, ExpressionType.Subtract); Assert (new MyType (-50), e4.Compile ().Invoke (new MyType (-20), new MyType (30))); Assert (null, e4.Compile ().Invoke (null, new MyType (30))); } void SubtractTest_5 () { Expression> e5 = (int a, MyType b) => a - b; AssertNodeType (e5, ExpressionType.Subtract); Assert (-29, e5.Compile ().Invoke (1, new MyType (30))); } void SubtractTest_6 () { Expression> e6 = (int a, MyType? b) => a - b; AssertNodeType (e6, ExpressionType.Subtract); Assert (-61, e6.Compile ().Invoke (-31, new MyType (30))); } void SubtractTest_7 () { Expression> e7 = (ushort a) => null - a; AssertNodeType (e7, ExpressionType.Subtract); Assert (null, e7.Compile ().Invoke (690)); } void SubtractTest_8 () { Expression> e8 = (a, b) => a - b; AssertNodeType (e8, ExpressionType.Convert); Assert ((MyEnum)255, e8.Compile ().Invoke (MyEnum.Value_1, 2)); } void SubtractTest_9 () { Expression> e9 = (a, b) => a - b; AssertNodeType (e9, ExpressionType.Convert); Assert (1, e9.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_1)); } void SubtractTest_10 () { Expression> e10 = (a, b) => a - b; AssertNodeType (e10, ExpressionType.Convert); Assert ((MyEnum) 255, e10.Compile ().Invoke (MyEnum.Value_1, 2)); } // CSC bug void SubtractTest_11 () { Expression> e11 = (a, b) => a - b; AssertNodeType (e11, ExpressionType.Convert); Assert (1, e11.Compile ().Invoke (MyEnum.Value_2, MyEnum.Value_1)); } void SubtractCheckedTest () { checked { Expression> e = (long a, long b) => a - b; AssertNodeType (e, ExpressionType.SubtractChecked); try { e.Compile ().Invoke (long.MinValue, 309); throw new ApplicationException ("SubtractCheckedTest #1"); } catch (OverflowException) { } } } void SubtractCheckedTest_2 () { checked { Expression> e2 = (a, b) => a - b; AssertNodeType (e2, ExpressionType.SubtractChecked); Assert (null, e2.Compile ().Invoke (null, 3)); Assert (-55, e2.Compile ().Invoke (byte.MinValue, 55)); } } void SubtractCheckedTest_3 () { checked { Expression> e3 = (MyType a, MyType b) => a - b; AssertNodeType (e3, ExpressionType.Subtract); Assert (-50, e3.Compile ().Invoke (new MyType (-20), new MyType (30))); } } void SubtractCheckedTest_4 () { checked { Expression> e4 = (a, b) => a - b; AssertNodeType (e4, ExpressionType.Subtract); Assert (double.PositiveInfinity, e4.Compile ().Invoke (double.MinValue, double.NegativeInfinity)); } } void TypeAsTest () { Expression> e = (object a) => a as Tester; AssertNodeType (e, ExpressionType.TypeAs); Assert (this, e.Compile ().Invoke (this)); } void TypeAsTest_2 () { Expression> e2 = (object a) => a as int?; AssertNodeType (e2, ExpressionType.TypeAs); Assert (null, e2.Compile ().Invoke (null)); Assert (null, e2.Compile ().Invoke (this)); Assert (44, e2.Compile ().Invoke (44)); } void TypeAsTest_3 () { Expression> e3 = (object a) => null as object; AssertNodeType (e3, ExpressionType.TypeAs); Assert (null, e3.Compile ().Invoke (null)); } void TypeAsTest_4 () { Expression> e = a => a as IConvertible; AssertNodeType (e, ExpressionType.TypeAs); Assert (ExpressionType.Parameter, ((UnaryExpression) e.Body).Operand.NodeType); Assert (5, e.Compile ().Invoke (5)); } void TypeIsTest () { Expression> e = (object a) => a is Tester; AssertNodeType (e, ExpressionType.TypeIs); Assert (true, e.Compile ().Invoke (this)); Assert (false, e.Compile ().Invoke (1)); } void TypeIsTest_2 () { Expression> e2 = (object a) => a is int?; AssertNodeType (e2, ExpressionType.TypeIs); Assert (false, e2.Compile ().Invoke (null)); Assert (true, e2.Compile ().Invoke (1)); } void TypeIsTest_3 () { Expression> e3 = (object a) => null is object; AssertNodeType (e3, ExpressionType.TypeIs); Assert (false, e3.Compile ().Invoke (null)); } void TypeIsTest_4 () { Expression> e = l => l is A; AssertNodeType (e, ExpressionType.TypeIs); Assert (false, e.Compile ().Invoke (null)); } void TypeIsTest_5 () { Expression> e5 = () => 1 is int; AssertNodeType (e5, ExpressionType.TypeIs); Assert (true, e5.Compile ().Invoke ()); } void TypeIsTest_6 () { Expression> e6 = (a) => a is int; AssertNodeType (e6, ExpressionType.TypeIs); Assert (true, e6.Compile ().Invoke (1)); Assert (false, e6.Compile ().Invoke (null)); } void UnaryPlusTest () { Expression> e = (a) => +a; AssertNodeType (e, ExpressionType.Parameter); Assert (-30, e.Compile ().Invoke (-30)); } void UnaryPlusTest_2 () { Expression> e2 = (a) => +a; AssertNodeType (e2, ExpressionType.Parameter); } void UnaryPlusTest_3 () { Expression> e4 = (a) => +a; AssertNodeType (e4, ExpressionType.UnaryPlus); Assert (new MyType (-14), e4.Compile ().Invoke (new MyType (-14))); } void UnaryPlusTest_4 () { Expression> e5 = (a) => +a; AssertNodeType (e5, ExpressionType.UnaryPlus); Assert (new MyType (33), e5.Compile ().Invoke (new MyType (33))); Assert (null, e5.Compile ().Invoke (null)); } void UnaryPlusTest_5 () { Expression> e6 = (a) => +a; AssertNodeType (e6, ExpressionType.Convert); Assert (3, e6.Compile ().Invoke (3)); Assert (null, e6.Compile ().Invoke (null)); } #pragma warning restore 169 // // Test helpers // string InstanceMethod (string arg) { return arg; } object InstanceParamsMethod (int index, params object [] args) { if (args == null) return ""; if (args.Length == 0) return ""; return args [index]; } static int TestInt () { return 29; } T GenericMethod (T t) { return t; } static void RefMethod (ref int i) { i = 867; } static bool RunTest (MethodInfo test) { Console.Write ("Running test {0, -25}", test.Name); try { test.Invoke (new Tester (), null); Console.WriteLine ("OK"); return true; } catch (Exception e) { Console.WriteLine ("FAILED"); Console.WriteLine (e.ToString ()); return false; } } public static int Main () { var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly) where test.GetParameters ().Length == 0 orderby test.Name select RunTest (test); int failures = tests.Count (a => !a); Console.WriteLine (failures + " tests failed"); return failures; } }