Added more tests.
[mono.git] / mcs / tests / gtest-etree-01.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Linq.Expressions;
5
6 public struct InverseLogicalOperator
7 {
8         bool value;
9         public InverseLogicalOperator (bool value)
10         {
11                 this.value = value;
12         }
13
14         public static bool operator true (InverseLogicalOperator u)
15         {
16                 return u.value;
17         }
18
19         public static bool operator false (InverseLogicalOperator u)
20         {
21                 return u.value;
22         }
23 }
24
25 /* TODO: Add tests for every numeric expression where a type has only 1 implicit
26                 numeric conversion
27 public struct MyType<T>
28 {
29         T value;
30
31         public MyType (T value)
32         {
33                 this.value = value;
34         }
35
36         public static implicit operator T (MyType<T> o)
37         {
38                 return o.value;
39         }
40 }
41 */
42
43
44 // TODO: Create a clone which uses +(MyType, int) pattern and an implicit conversion
45 // is required to do the user-conversion
46
47 public struct MyType
48 {
49         int value;
50
51         public MyType (int value)
52         {
53                 this.value = value;
54         }
55         
56         public override int GetHashCode ()
57         {
58                 throw new NotImplementedException ();
59         }
60
61         public static implicit operator int (MyType o)
62         {
63                 return o.value;
64         }
65
66         public static bool operator true (MyType a)
67         {
68                 return a.value == a;
69         }
70
71         public static bool operator false (MyType a)
72         {
73                 return a.value != a;
74         }
75
76         public static MyType operator +(MyType a, MyType b)
77         {
78                 return new MyType (a.value + b.value);
79         }
80
81         public static MyType operator / (MyType a, MyType b)
82         {
83                 return new MyType (a.value / b.value);
84         }
85
86         public static MyType operator &(MyType a, MyType b)
87         {
88                 return new MyType (a.value & b.value);
89         }
90
91         public static MyType operator | (MyType a, MyType b)
92         {
93                 return new MyType (a.value | b.value);
94         }
95
96         public static MyType operator ^ (MyType a, MyType b)
97         {
98                 return new MyType (a.value ^ b.value);
99         }
100
101         public static bool operator == (MyType a, MyType b)
102         {
103                 return a.value == b.value;
104         }
105
106         public static bool operator != (MyType a, MyType b)
107         {
108                 return a.value != b.value;
109         }
110         
111         public static bool operator > (MyType a, MyType b)
112         {
113                 return a.value > b.value;
114         }
115
116         public static bool operator < (MyType a, MyType b)
117         {
118                 return a.value < b.value;
119         }
120
121         public static bool operator >= (MyType a, MyType b)
122         {
123                 return a.value >= b.value;
124         }
125         
126         public static bool operator <= (MyType a, MyType b)
127         {
128                 return a.value <= b.value;
129         }
130
131         public static bool operator ! (MyType a)
132         {
133                 return a.value > 0;
134         }
135
136         public static int operator >> (MyType a, int b)
137         {
138                 return a.value >> b;
139         }
140
141         public override string ToString ()
142         {
143                 return value.ToString ();
144         }
145 }
146
147
148 class MyTypeExplicit
149 {
150         int value;
151         
152         public MyTypeExplicit (int value)
153         {
154                 this.value = value;
155         }
156         
157         public static explicit operator int (MyTypeExplicit m)
158         {
159                 return m.value;
160         }
161 }
162
163 // TODO: Add more nullable tests, follow AddTest pattern.
164
165 class Tester
166 {
167         static void AssertNodeType (LambdaExpression e, ExpressionType et)
168         {
169                 if (e.Body.NodeType != et)
170                         throw new ApplicationException (e.Body.NodeType + " != " + et);
171         }
172
173         static void Assert<T> (T expected, T value)
174         {
175                 Assert (expected, value, null);
176         }
177
178         static void Assert<T> (T expected, T value, string name)
179         {
180                 if (!EqualityComparer<T>.Default.Equals (expected, value)) {
181                         if (!string.IsNullOrEmpty (name))
182                                 name += ": ";
183                         throw new ApplicationException (name + expected + " != " + value);
184                 }
185         }
186
187         static void Assert<T> (T [] expected, T [] value)
188         {
189                 if (expected.Length != value.Length)
190                         throw new ApplicationException ("Array length does not match " + expected.Length + " != " + value.Length);
191
192                 for (int i = 0; i < expected.Length; ++i) {
193                         if (!EqualityComparer<T>.Default.Equals (expected [i], value [i]))
194                                 throw new ApplicationException ("Index " + i + ": " + expected [i] + " != " + value [i]);
195                 }
196         }
197
198         void AddTest ()
199         {
200                 Expression<Func<int, int, int>> e = (int a, int b) => a + b;
201                 AssertNodeType (e, ExpressionType.Add);
202                 Assert (50, e.Compile ().Invoke (20, 30));
203
204                 Expression<Func<int?, int?, int?>> e2 = (a, b) => a + b;
205                 AssertNodeType (e2, ExpressionType.Add);
206                 Assert (null, e2.Compile ().Invoke (null, 3));
207
208                 Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a + b;
209                 AssertNodeType (e3, ExpressionType.Add);
210                 Assert (10, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
211
212                 Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a + b;
213                 AssertNodeType (e4, ExpressionType.Add);
214                 Assert (new MyType (10), e4.Compile ().Invoke (new MyType (-20), new MyType (30)));
215                 Assert (null, e4.Compile ().Invoke (null, new MyType (30)));
216
217                 Expression<Func<int, MyType, int>> e5 = (int a, MyType b) => a + b;
218                 AssertNodeType (e5, ExpressionType.Add);
219                 Assert (31, e5.Compile ().Invoke (1, new MyType (30)));
220
221                 Expression<Func<int, MyType?, int?>> e6 = (int a, MyType? b) => a + b;
222                 AssertNodeType (e6, ExpressionType.Add);
223                 Assert (-1, e6.Compile ().Invoke (-31, new MyType (30)));
224         }
225
226         void AddCheckedTest ()
227         {
228                 checked {
229                 Expression<Func<int, int, int>> e = (int a, int b) => a + b;
230                 AssertNodeType (e, ExpressionType.AddChecked);
231                 Assert (50, e.Compile ().Invoke (20, 30));
232
233                 Expression<Func<int?, int?, int?>> e2 = (a, b) => a + b;
234                 AssertNodeType (e2, ExpressionType.AddChecked);
235                 Assert (null, e2.Compile ().Invoke (null, 3));
236
237                 Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a + b;
238                 AssertNodeType (e3, ExpressionType.Add);
239                 Assert (10, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
240                 }
241         }
242         
243         void AddStringTest ()
244         {
245                 Expression<Func<string, string>> e6 = (a) => 1 + a;
246                 AssertNodeType (e6, ExpressionType.Add);
247                 Assert ("1to", e6.Compile ().Invoke ("to"));
248         
249                 Expression<Func<object, string, string>> e7 = (object a, string b) => a + b;
250                 AssertNodeType (e7, ExpressionType.Add);
251                 Assert ("testme", e7.Compile ().Invoke ("test", "me"));
252                 Assert ("test", e7.Compile ().Invoke ("test", null));
253                 Assert ("", e7.Compile ().Invoke (null, null));
254
255                 Expression<Func<string, int, string>> e8 = (a, b) => a + " " + "-" + "> " + b;
256                 AssertNodeType (e8, ExpressionType.Add);
257                 Assert ("test -> 2", e8.Compile ().Invoke ("test", 2));
258
259                 Expression<Func<string, ushort?, string>> e9 = (a, b) => a + b;
260                 AssertNodeType (e9, ExpressionType.Add);
261                 Assert ("test2", e9.Compile ().Invoke ("test", 2));
262                 Assert ("test", e9.Compile ().Invoke ("test", null));   
263         }
264
265         void AndTest ()
266         {
267                 Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a & b;
268
269                 AssertNodeType (e, ExpressionType.And);
270                 Func<bool, bool, bool> c = e.Compile ();
271
272                 Assert (true, c (true, true));
273                 Assert (false, c (true, false));
274                 Assert (false, c (false, true));
275                 Assert (false, c (false, false));
276
277                 Expression<Func<MyType, MyType, MyType>> e2 = (MyType a, MyType b) => a & b;
278
279                 AssertNodeType (e2, ExpressionType.And);
280                 var c2 = e2.Compile ();
281
282                 Assert (new MyType (0), c2 (new MyType (0), new MyType (1)));
283                 Assert (new MyType (1), c2 (new MyType (0xFF), new MyType (0x01)));
284         }
285
286         void AndNullableTest ()
287         {
288                 Expression<Func<bool?, bool?, bool?>> e = (bool? a, bool? b) => a & b;
289
290                 AssertNodeType (e, ExpressionType.And);
291                 Func<bool?, bool?, bool?> c = e.Compile ();
292
293                 Assert (true, c (true, true));
294                 Assert (false, c (true, false));
295                 Assert (false, c (false, true));
296                 Assert (false, c (false, false));
297
298                 Assert (null, c (true, null));
299                 Assert (false, c (false, null));
300                 Assert (false, c (null, false));
301                 Assert (null, c (true, null));
302                 Assert (null, c (null, null));
303
304                 Expression<Func<MyType?, MyType?, MyType?>> e2 = (MyType? a, MyType? b) => a & b;
305
306                 AssertNodeType (e2, ExpressionType.And);
307                 var c2 = e2.Compile ();
308
309                 Assert (new MyType (0), c2 (new MyType (0), new MyType (1)));
310                 Assert (new MyType (1), c2 (new MyType (0xFF), new MyType (0x01)));
311                 Assert (null, c2 (new MyType (0xFF), null));
312         }
313
314         void AndAlsoTest ()
315         {
316                 Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a && b;
317                 AssertNodeType (e, ExpressionType.AndAlso);
318                 Assert (false, e.Compile ().Invoke (true, false));
319
320                 Expression<Func<MyType, MyType, MyType>> e2 = (MyType a, MyType b) => a && b;
321                 AssertNodeType (e2, ExpressionType.AndAlso);
322                 Assert (new MyType (64), e2.Compile ().Invoke (new MyType (64), new MyType (64)));
323                 Assert (new MyType (0), e2.Compile ().Invoke (new MyType (32), new MyType (64)));
324
325                 Expression<Func<bool, bool>> e3 = (bool a) => a && true;
326                 AssertNodeType (e3, ExpressionType.AndAlso);
327                 Assert (false, e3.Compile ().Invoke (false));
328                 Assert (true, e3.Compile ().Invoke (true));
329         }
330
331         void ArrayIndexTest ()
332         {
333                 Expression<Func<string [], long, string>> e = (string [] a, long i) => a [i];
334                 AssertNodeType (e, ExpressionType.ArrayIndex);
335                 Assert ("b", e.Compile ().Invoke (new string [] { "a", "b", "c" }, 1));
336
337                 Expression<Func<string [], string>> e2 = (string [] a) => a [0];
338                 AssertNodeType (e2, ExpressionType.ArrayIndex);
339                 Assert ("a", e2.Compile ().Invoke (new string [] { "a", "b" }));
340
341                 Expression<Func<object [,], int, int, object>> e3 = (object [,] a, int i, int j) => a [i, j];
342                 AssertNodeType (e3, ExpressionType.Call);
343
344                 Assert ("z", e3.Compile ().Invoke (
345                         new object [,] { { 1, 2 }, { "x", "z" } }, 1, 1));
346
347                 Expression<Func<decimal [] [], byte, decimal>> e4 = (decimal [] [] a, byte b) => a [b] [1];
348                 AssertNodeType (e4, ExpressionType.ArrayIndex);
349
350                 decimal [] [] array = { new decimal [] { 1, 9 }, new decimal [] { 10, 90 } };
351                 Assert (90, e4.Compile ().Invoke (array, 1));
352         }
353
354         void ArrayLengthTest ()
355         {
356                 Expression<Func<double [], int>> e = (double [] a) => a.Length;
357                 AssertNodeType (e, ExpressionType.ArrayLength);
358                 Assert (0, e.Compile ().Invoke (new double [0]));
359                 Assert (9, e.Compile ().Invoke (new double [9]));
360
361                 // TODO: implement
362                 //Expression<Func<string [,], int>> e2 = (string [,] a) => a.Length;
363                 //AssertNodeType (e2, ExpressionType.MemberAccess);
364                 //Assert (0, e2.Compile ().Invoke (new string [0, 0]));
365         }
366
367         void CallTest ()
368         {
369                 Expression<Func<int, int>> e = (int a) => Math.Max (a, 5);
370                 AssertNodeType (e, ExpressionType.Call);
371                 Assert (5, e.Compile ().Invoke (2));
372                 Assert (9, e.Compile ().Invoke (9));
373
374                 Expression<Func<string, string>> e2 = (string a) => InstanceMethod (a);
375                 AssertNodeType (e2, ExpressionType.Call);
376                 Assert ("abc", e2.Compile ().Invoke ("abc"));
377
378                 Expression<Func<int, string, int, object>> e3 = (int index, string a, int b) => InstanceParamsMethod (index, a, b);
379                 AssertNodeType (e3, ExpressionType.Call);
380                 Assert<object> (4, e3.Compile ().Invoke (1, "a", 4));
381
382                 Expression<Func<object>> e4 = () => InstanceParamsMethod (0);
383                 AssertNodeType (e4, ExpressionType.Call);
384                 Assert<object> ("<empty>", e4.Compile ().Invoke ());
385
386                 Expression<Func<int, int>> e5 = (int a) => GenericMethod (a);
387                 AssertNodeType (e5, ExpressionType.Call);
388                 Assert (5, e5.Compile ().Invoke (5));
389         }
390
391         void CoalesceTest ()
392         {
393                 Expression<Func<uint?, uint>> e = (uint? a) => a ?? 99;
394                 AssertNodeType (e, ExpressionType.Coalesce);
395                 var r = e.Compile ();
396                 Assert ((uint) 5, r.Invoke (5));
397                 Assert ((uint) 99, r.Invoke (null));
398
399                 Expression<Func<MyType?, int>> e2 = (MyType? a) => a ?? -3;
400                 AssertNodeType (e2, ExpressionType.Coalesce);
401                 var r2 = e2.Compile ();
402                 Assert (2, r2.Invoke (new MyType (2)));
403                 Assert (-3, r2.Invoke (null));
404         }
405
406         void ConditionTest ()
407         {
408                 Expression<Func<bool, byte, int, int>> e = (bool a, byte b, int c) => (a ? b : c);
409                 AssertNodeType (e, ExpressionType.Conditional);
410                 var r = e.Compile ();
411                 Assert (3, r.Invoke (true, 3, 999999));
412                 Assert (999999, r.Invoke (false, 3, 999999));
413
414                 Expression<Func<int, decimal, decimal?>> e2 = (int a, decimal d) => (a > 0 ? d : a < 0 ? -d : (decimal?) null);
415                 AssertNodeType (e2, ExpressionType.Conditional);
416                 var r2 = e2.Compile ();
417                 Assert (null, r2.Invoke (0, 10));
418                 Assert (50, r2.Invoke (1, 50));
419                 Assert (30, r2.Invoke (-7, -30));
420
421                 Expression<Func<bool?, int?>> e3 = (bool? a) => ((bool) a ? 3 : -2);
422                 AssertNodeType (e3, ExpressionType.Convert);
423                 var r3 = e3.Compile ();
424                 Assert (3, r3.Invoke (true));
425                 Assert (-2, r3.Invoke (false));
426
427                 Expression<Func<InverseLogicalOperator, byte, byte, byte>> e4 = (InverseLogicalOperator a, byte b, byte c) => (a ? b : c);
428                 AssertNodeType (e4, ExpressionType.Conditional);
429                 var r4 = e4.Compile ();
430                 Assert (3, r4.Invoke (new InverseLogicalOperator (true), 3, 4));
431                 Assert (4, r4.Invoke (new InverseLogicalOperator (false), 3, 4));
432         }
433         
434         void ConstantTest ()
435         {
436                 Expression<Func<int>> e1 = () => default (int);
437                 AssertNodeType (e1, ExpressionType.Constant);
438                 Assert (0, e1.Compile ().Invoke ());
439
440                 Expression<Func<int?>> e2 = () => default (int?);
441                 AssertNodeType (e2, ExpressionType.Constant);
442                 Assert (null, e2.Compile ().Invoke ());
443                 
444                 Expression<Func<Tester>> e3 = () => default (Tester);
445                 AssertNodeType (e3, ExpressionType.Constant);
446                 Assert (null, e3.Compile ().Invoke ());
447                 
448                 Expression<Func<object>> e4 = () => null;
449                 AssertNodeType (e4, ExpressionType.Constant);
450                 Assert (null, e4.Compile ().Invoke ());
451
452                 Expression<Func<int>> e5 = () => 8 / 4;
453                 AssertNodeType (e5, ExpressionType.Constant);
454                 Assert (2, e5.Compile ().Invoke ());
455
456                 Expression<Func<int>> e6 = () => 0xFFFFFF >> 0x40;
457                 AssertNodeType (e6, ExpressionType.Constant);
458                 Assert (0xFFFFFF, e6.Compile ().Invoke ());
459         }
460
461         void ConvertTest ()
462         {
463                 Expression<Func<int, byte>> e = (int a) => ((byte) a);
464                 AssertNodeType (e, ExpressionType.Convert);
465                 Assert (100, e.Compile ().Invoke (100));
466
467                 Expression<Func<long, ushort>> e2 = (long a) => ((ushort) a);
468                 AssertNodeType (e2, ExpressionType.Convert);
469                 Assert (100, e2.Compile ().Invoke (100));
470
471                 Expression<Func<float?, float>> e3 = (float? a) => ((float) a);
472                 AssertNodeType (e3, ExpressionType.Convert);
473                 Assert (-0.456f, e3.Compile ().Invoke (-0.456f));
474
475                 Expression<Func<MyType, int>> e4 = (MyType a) => (a);
476                 AssertNodeType (e4, ExpressionType.Convert);
477                 Assert (-9, e4.Compile ().Invoke (new MyType (-9)));
478
479                 Expression<Func<MyType, MyType, bool?>> e5 = (MyType a, MyType b) => a == b;
480                 AssertNodeType (e5, ExpressionType.Convert);
481
482                 Expression<Func<MyType?, MyType?, bool?>> e6 = (MyType? a, MyType? b) => a == b;
483                 AssertNodeType (e6, ExpressionType.Convert);
484                 Assert (false, e6.Compile ().Invoke (null, new MyType (-20)));
485                 Assert (true, e6.Compile ().Invoke (null, null));
486                 Assert (true, e6.Compile ().Invoke (new MyType (120), new MyType (120)));
487                 
488                 // TODO: redundant return conversion
489                 // Expression<Func<MyTypeExplicit, int?>> e6 = x => (int?)x;
490                 
491                 // TODO: redundant convert
492                 // TODO: pass null value
493                 // Expression<Func<int?, object>> ex = x => (object)x;
494         }
495
496         void ConvertCheckedTest ()
497         {
498                 Expression<Func<int, byte>> e = (int a) => checked((byte) a);
499                 AssertNodeType (e, ExpressionType.ConvertChecked);
500                 Assert (100, e.Compile ().Invoke (100));
501
502                 checked {
503                         Expression<Func<long, ushort>> e2 = (long a) => unchecked((ushort) a);
504                         AssertNodeType (e2, ExpressionType.Convert);
505                         Assert (100, e2.Compile ().Invoke (100));
506
507                         Expression<Func<float?, float>> e3 = (float? a) => ((float) a);
508                         AssertNodeType (e3, ExpressionType.ConvertChecked);
509                         Assert (-0.456f, e3.Compile ().Invoke (-0.456f));
510
511                         Expression<Func<MyType, int>> e4 = (MyType a) => (a);
512                         AssertNodeType (e4, ExpressionType.Convert);
513                         Assert (-9, e4.Compile ().Invoke (new MyType (-9)));
514                 }
515         }
516
517         void DivideTest ()
518         {
519                 Expression<Func<int, int, int>> e = (int a, int b) => a / b;
520                 AssertNodeType (e, ExpressionType.Divide);
521                 Assert (2, e.Compile ().Invoke (60, 30));
522
523                 Expression<Func<double?, double?, double?>> e2 = (a, b) => a / b;
524                 AssertNodeType (e2, ExpressionType.Divide);
525                 Assert (null, e2.Compile ().Invoke (null, 3));
526                 Assert (1.5, e2.Compile ().Invoke (3, 2));
527
528                 Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a / b;
529                 AssertNodeType (e3, ExpressionType.Divide);
530                 Assert (1, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
531
532                 Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a / b;
533                 AssertNodeType (e4, ExpressionType.Divide);
534                 Assert (null, e4.Compile ().Invoke (null, new MyType (-20)));
535                 Assert (new MyType (-6), e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
536
537                 Expression<Func<int, MyType, int>> e5 = (int a, MyType b) => a / b;
538                 AssertNodeType (e5, ExpressionType.Divide);
539                 Assert (50, e5.Compile ().Invoke (100, new MyType (2)));
540                 
541                 Expression<Func<int, MyType?, int?>> e6 = (int a, MyType? b) => a / b;
542                 AssertNodeType (e6, ExpressionType.Divide);
543                 Assert (50, e6.Compile ().Invoke (100, new MyType (2)));
544                 Assert (null, e6.Compile ().Invoke (20, null));
545         }
546
547         void EqualTest ()
548         {
549                 Expression<Func<int, int, bool>> e = (int a, int b) => a == b;
550                 AssertNodeType (e, ExpressionType.Equal);
551                 Assert (false, e.Compile ().Invoke (60, 30));
552                 Assert (true, e.Compile ().Invoke (-1, -1));
553
554                 Expression<Func<double?, double?, bool>> e2 = (a, b) => a == b;
555                 AssertNodeType (e2, ExpressionType.Equal);
556                 Assert (true, e2.Compile ().Invoke (3, 3));
557                 Assert (false, e2.Compile ().Invoke (3, 2));
558
559                 Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a == b;
560                 AssertNodeType (e3, ExpressionType.Equal);
561                 Assert (true, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
562
563                 Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a == b;
564                 AssertNodeType (e4, ExpressionType.Equal);
565                 Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
566                 Assert (true, e4.Compile ().Invoke (null, null));
567                 Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (120)));
568
569                 Expression<Func<bool?, bool?, bool>> e5 = (bool? a, bool? b) => a == b;
570                 AssertNodeType (e5, ExpressionType.Equal);
571                 Assert (false, e5.Compile ().Invoke (true, null));
572                 Assert (true, e5.Compile ().Invoke (null, null));
573                 Assert (true, e5.Compile ().Invoke (false, false));
574                 
575                 Expression<Func<bool, bool>> e6 = (bool a) => a == null;
576                 AssertNodeType (e6, ExpressionType.Equal);
577                 Assert (false, e6.Compile ().Invoke (true));
578                 Assert (false, e6.Compile ().Invoke (false));
579
580                 Expression<Func<string, string, bool>> e7 = (string a, string b) => a == b;
581                 AssertNodeType (e7, ExpressionType.Equal);
582                 Assert (true, e7.Compile ().Invoke (null, null));
583                 Assert (false, e7.Compile ().Invoke ("a", "A"));
584                 Assert (true, e7.Compile ().Invoke ("a", "a"));
585
586                 Expression<Func<object, bool>> e8 = (object a) => null == a;
587                 AssertNodeType (e8, ExpressionType.Equal);
588                 Assert (true, e8.Compile ().Invoke (null));
589                 Assert (false, e8.Compile ().Invoke ("a"));
590                 Assert (false, e8.Compile ().Invoke (this));
591         }
592
593         delegate void EmptyDelegate ();
594         
595         void EqualTestDelegate ()
596         {
597                 Expression<Func<Delegate, Delegate, bool>> e1 = (a, b) => a == b;
598                 AssertNodeType (e1, ExpressionType.Equal);
599                 Assert (true, e1.Compile ().Invoke (null, null));
600
601                 EmptyDelegate ed = delegate () {};
602
603                 Expression<Func<EmptyDelegate, EmptyDelegate, bool>> e2 = (a, b) => a == b;
604                 AssertNodeType (e2, ExpressionType.Equal);
605                 Assert (false, e2.Compile ().Invoke (delegate () {}, null));
606                 Assert (false, e2.Compile ().Invoke (delegate () {}, delegate {}));
607                 Assert (false, e2.Compile ().Invoke (ed, delegate {}));
608                 Assert (true, e2.Compile ().Invoke (ed, ed));
609         }       
610
611         void ExclusiveOrTest ()
612         {
613                 Expression<Func<int, short, int>> e = (int a, short b) => a ^ b;
614                 AssertNodeType (e, ExpressionType.ExclusiveOr);
615                 Assert (34, e.Compile ().Invoke (60, 30));
616
617                 Expression<Func<byte?, byte?, int?>> e2 = (a, b) => a ^ b;
618                 AssertNodeType (e2, ExpressionType.ExclusiveOr);
619                 Assert (null, e2.Compile ().Invoke (null, 3));
620                 Assert (1, e2.Compile ().Invoke (3, 2));
621
622                 Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a ^ b;
623                 AssertNodeType (e3, ExpressionType.ExclusiveOr);
624                 Assert (0, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
625
626                 Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a ^ b;
627                 AssertNodeType (e4, ExpressionType.ExclusiveOr);
628                 Assert (null, e4.Compile ().Invoke (null, new MyType (-20)));
629                 Assert (new MyType (-108), e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
630
631                 Expression<Func<MyType?, byte, int?>> e5 = (MyType? a, byte b) => a ^ b;
632                 AssertNodeType (e5, ExpressionType.ExclusiveOr);
633                 Assert (null, e5.Compile ().Invoke (null, 64));
634                 Assert (96, e5.Compile ().Invoke (new MyType (64), 32));
635         }
636
637         void GreaterThanTest ()
638         {
639                 Expression<Func<int, int, bool>> e = (int a, int b) => a > b;
640                 AssertNodeType (e, ExpressionType.GreaterThan);
641                 Assert (true, e.Compile ().Invoke (60, 30));
642
643                 Expression<Func<uint?, byte?, bool>> e2 = (a, b) => a > b;
644                 AssertNodeType (e2, ExpressionType.GreaterThan);
645                 Assert (false, e2.Compile ().Invoke (null, 3));
646                 Assert (false, e2.Compile ().Invoke (2, 2));
647
648                 Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a > b;
649                 AssertNodeType (e3, ExpressionType.GreaterThan);
650                 Assert (false, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
651
652                 Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a > b;
653                 AssertNodeType (e4, ExpressionType.GreaterThan);
654                 Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
655                 Assert (false, e4.Compile ().Invoke (null, null));
656                 Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
657
658                 Expression<Func<MyType?, sbyte, bool>> e5 = (MyType? a, sbyte b) => a > b;
659                 AssertNodeType (e5, ExpressionType.GreaterThan);
660                 Assert (false, e5.Compile ().Invoke (null, 33));
661                 Assert (false, e5.Compile ().Invoke (null, 0));
662                 Assert (true, e5.Compile ().Invoke (new MyType (120), 3));
663
664                 Expression<Func<ushort, bool>> e6 = (ushort a) => a > null;
665                 AssertNodeType (e6, ExpressionType.GreaterThan);
666                 Assert (false, e6.Compile ().Invoke (60));
667         }
668
669         void GreaterThanOrEqualTest ()
670         {
671                 Expression<Func<int, int, bool>> e = (int a, int b) => a >= b;
672                 AssertNodeType (e, ExpressionType.GreaterThanOrEqual);
673                 Assert (true, e.Compile ().Invoke (60, 30));
674
675                 Expression<Func<byte?, byte?, bool>> e2 = (a, b) => a >= b;
676                 AssertNodeType (e2, ExpressionType.GreaterThanOrEqual);
677                 Assert (false, e2.Compile ().Invoke (null, 3));
678                 Assert (true, e2.Compile ().Invoke (2, 2));
679
680                 Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a >= b;
681                 AssertNodeType (e3, ExpressionType.GreaterThanOrEqual);
682                 Assert (true, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)), "D1");
683
684                 Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a >= b;
685                 AssertNodeType (e4, ExpressionType.GreaterThanOrEqual);
686                 Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
687                 Assert (false, e4.Compile ().Invoke (null, null));
688                 Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
689
690                 Expression<Func<MyType?, sbyte, bool>> e5 = (MyType? a, sbyte b) => a >= b;
691                 AssertNodeType (e5, ExpressionType.GreaterThanOrEqual);
692                 Assert (false, e5.Compile ().Invoke (null, 33));
693                 Assert (false, e5.Compile ().Invoke (null, 0));
694                 Assert (true, e5.Compile ().Invoke (new MyType (120), 3));
695
696                 Expression<Func<ushort, bool>> e6 = (ushort a) => a >= null;
697                 AssertNodeType (e6, ExpressionType.GreaterThanOrEqual);
698                 Assert (false, e6.Compile ().Invoke (60));
699         }
700
701         void NewArrayInitTest ()
702         {
703                 Expression<Func<int []>> e = () => new int [0];
704                 AssertNodeType (e, ExpressionType.NewArrayInit);
705                 Assert (new int [0], e.Compile ().Invoke ());
706
707                 e = () => new int [] { };
708                 AssertNodeType (e, ExpressionType.NewArrayInit);
709                 Assert (new int [0], e.Compile ().Invoke ());
710
711                 Expression<Func<ushort, ulong? []>> e2 = (ushort a) => new ulong? [] { a };
712                 AssertNodeType (e2, ExpressionType.NewArrayInit);
713                 Assert (new ulong? [1] { ushort.MaxValue }, e2.Compile ().Invoke (ushort.MaxValue));
714
715                 Expression<Func<char [] []>> e3 = () => new char [] [] { new char [] { 'a' } };
716                 AssertNodeType (e3, ExpressionType.NewArrayInit);
717                 Assert (new char [] { 'a' }, e3.Compile ().Invoke () [0]);
718         }
719
720         void NotTest ()
721         {
722                 Expression<Func<bool, bool>> e = (bool a) => !a;
723                 AssertNodeType (e, ExpressionType.Not);
724                 Assert (false, e.Compile ().Invoke (true));
725
726                 Expression<Func<MyType, bool>> e2 = (MyType a) => !a;
727                 AssertNodeType (e2, ExpressionType.Not);
728                 Assert (true, e2.Compile ().Invoke (new MyType (1)));
729                 Assert (false, e2.Compile ().Invoke (new MyType (-1)));
730         }
731
732         void NotNullableTest ()
733         {
734                 Expression<Func<bool?, bool?>> e = (bool? a) => !a;
735                 AssertNodeType (e, ExpressionType.Not);
736                 Assert (false, e.Compile ().Invoke (true));
737                 Assert (null, e.Compile ().Invoke (null));
738
739                 Expression<Func<MyType?, bool?>> e2 = (MyType? a) => !a;
740                 AssertNodeType (e2, ExpressionType.Not);
741                 Assert (true, e2.Compile ().Invoke (new MyType (1)));
742                 Assert (null, e2.Compile ().Invoke (null));
743         }
744
745         void NotEqualTest ()
746         {
747                 Expression<Func<int, int, bool>> e = (int a, int b) => a != b;
748                 AssertNodeType (e, ExpressionType.NotEqual);
749                 Assert (true, e.Compile ().Invoke (60, 30));
750                 Assert (false, e.Compile ().Invoke (-1, -1));
751
752                 Expression<Func<sbyte?, sbyte?, bool>> e2 = (a, b) => a != b;
753                 AssertNodeType (e2, ExpressionType.NotEqual);
754                 Assert (false, e2.Compile ().Invoke (3, 3));
755                 Assert (true, e2.Compile ().Invoke (3, 2));
756
757                 Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a != b;
758                 AssertNodeType (e3, ExpressionType.NotEqual);
759                 Assert (false, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
760
761                 Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a != b;
762                 AssertNodeType (e4, ExpressionType.NotEqual);
763                 Assert (true, e4.Compile ().Invoke (null, new MyType (-20)));
764                 Assert (false, e4.Compile ().Invoke (null, null));
765                 Assert (false, e4.Compile ().Invoke (new MyType (120), new MyType (120)));
766
767                 Expression<Func<bool?, bool?, bool>> e5 = (bool? a, bool? b) => a != b;
768                 AssertNodeType (e5, ExpressionType.NotEqual);
769                 Assert (true, e5.Compile ().Invoke (true, null));
770                 Assert (false, e5.Compile ().Invoke (null, null));
771                 Assert (false, e5.Compile ().Invoke (false, false));
772
773                 Expression<Func<bool, bool>> e6 = (bool a) => a != null;
774                 AssertNodeType (e6, ExpressionType.NotEqual);
775                 Assert (true, e6.Compile ().Invoke (true));
776                 Assert (true, e6.Compile ().Invoke (false));
777
778                 Expression<Func<string, string, bool>> e7 = (string a, string b) => a != b;
779                 AssertNodeType (e7, ExpressionType.NotEqual);
780                 Assert (false, e7.Compile ().Invoke (null, null));
781                 Assert (true, e7.Compile ().Invoke ("a", "A"));
782                 Assert (false, e7.Compile ().Invoke ("a", "a"));
783
784                 Expression<Func<object, bool>> e8 = (object a) => null != a;
785                 AssertNodeType (e8, ExpressionType.NotEqual);
786                 Assert (false, e8.Compile ().Invoke (null));
787                 Assert (true, e8.Compile ().Invoke ("a"));
788                 Assert (true, e8.Compile ().Invoke (this));
789         }
790
791         void OrTest ()
792         {
793                 Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a | b;
794
795                 AssertNodeType (e, ExpressionType.Or);
796                 Func<bool, bool, bool> c = e.Compile ();
797
798                 Assert (true, c (true, true));
799                 Assert (true, c (true, false));
800                 Assert (true, c (false, true));
801                 Assert (false, c (false, false));
802
803                 Expression<Func<MyType, MyType, MyType>> e2 = (MyType a, MyType b) => a | b;
804                 AssertNodeType (e2, ExpressionType.Or);
805                 var c2 = e2.Compile ();
806                 Assert (new MyType (3), c2 (new MyType (1), new MyType (2)));
807         }
808
809         void OrNullableTest ()
810         {
811                 Expression<Func<bool?, bool?, bool?>> e = (bool? a, bool? b) => a | b;
812
813                 AssertNodeType (e, ExpressionType.Or);
814                 Func<bool?, bool?, bool?> c = e.Compile ();
815
816                 Assert (true, c (true, true));
817                 Assert (true, c (true, false));
818                 Assert (true, c (false, true));
819                 Assert (false, c (false, false));
820
821                 Assert (true, c (true, null));
822                 Assert (null, c (false, null));
823                 Assert (null, c (null, false));
824                 Assert (true, c (true, null));
825                 Assert (null, c (null, null));
826
827                 Expression<Func<MyType?, MyType?, MyType?>> e2 = (MyType? a, MyType? b) => a | b;
828                 AssertNodeType (e2, ExpressionType.Or);
829                 var c2 = e2.Compile ();
830                 Assert (new MyType (3), c2 (new MyType (1), new MyType (2)));
831                 Assert (null, c2 (new MyType (1), null));
832
833                 /* BUG: This does not work with csc either, because nullable conversions on top of user conversion is required
834                 
835                 Expression<Func<MyType?, uint, long?>> e3 = (MyType? a, uint b) => a | b;
836                 AssertNodeType (e3, ExpressionType.Or);
837                 var c3 = e3.Compile ();
838                 Assert (9, c3 (new MyType (1), 8));
839                 Assert (null, c3 (null, 4));
840                 */
841         }
842
843         void OrElseTest ()
844         {
845                 Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a || b;
846                 AssertNodeType (e, ExpressionType.OrElse);
847                 Assert (true, e.Compile ().Invoke (true, false));
848
849                 Expression<Func<MyType, MyType, MyType>> e2 = (MyType a, MyType b) => a || b;
850                 AssertNodeType (e2, ExpressionType.OrElse);
851                 Assert (new MyType (64), e2.Compile ().Invoke (new MyType (64), new MyType (64)));
852                 Assert (new MyType (32), e2.Compile ().Invoke (new MyType (32), new MyType (64)));
853         }
854
855         void ParameterTest ()
856         {
857                 Expression<Func<string, string>> e = (string a) => a;
858                 AssertNodeType (e, ExpressionType.Parameter);
859                 Assert ("t", e.Compile ().Invoke ("t"));
860
861                 Expression<Func<object[], object[]>> e2 = (object[] a) => a;
862                 AssertNodeType (e2, ExpressionType.Parameter);
863                 Assert (new object [0], e2.Compile ().Invoke (new object [0]));
864
865                 Expression<Func<IntPtr, IntPtr>> e3 = a => a;
866                 AssertNodeType (e3, ExpressionType.Parameter);
867                 Assert (IntPtr.Zero, e3.Compile ().Invoke (IntPtr.Zero));
868         }
869
870         void QuoteTest ()
871         {
872                 Expression<Func<Expression<Func<int>>>> e = () => () => 2;
873                 AssertNodeType (e, ExpressionType.Quote);
874                 Assert (2, e.Compile ().Invoke ().Compile ().Invoke ());
875         }
876
877         void RightShiftTest ()
878         {
879                 Expression<Func<ulong, short, ulong>> e = (ulong a, short b) => a >> b;
880                 AssertNodeType (e, ExpressionType.RightShift);
881                 Assert ((ulong)0x1FD940L, e.Compile ().Invoke (0xFECA0000, 11));
882                 Assert ((ulong)0, e.Compile ().Invoke (0xFFFFFFFF, 0xA01));
883
884                 Expression<Func<MyType, MyType, int>> e2 = (MyType a, MyType b) => a >> b;
885                 AssertNodeType (e2, ExpressionType.RightShift);
886                 var c2 = e2.Compile ();
887                 Assert (64, c2 (new MyType (256), new MyType (2)));
888                 
889                 Expression<Func<long?, sbyte, long?>> e3 = (long? a, sbyte b) => a >> b;
890                 AssertNodeType (e3, ExpressionType.RightShift);
891                 Assert (null, e3.Compile ().Invoke (null, 11));
892                 Assert (512, e3.Compile ().Invoke (1024, 1));
893
894                 Expression<Func<MyType?, MyType?, int?>> e4 = (MyType? a, MyType? b) => a >> b;
895                 AssertNodeType (e4, ExpressionType.RightShift);
896                 var c4 = e4.Compile ();
897                 Assert (null, c4 (new MyType (8), null));
898                 Assert (null, c4 (null, new MyType (8)));
899                 Assert (64, c4 (new MyType (256), new MyType (2)));
900         }
901
902         //
903         // Test helpers
904         //
905         string InstanceMethod (string arg)
906         {
907                 return arg;
908         }
909
910         object InstanceParamsMethod (int index, params object [] args)
911         {
912                 if (args == null)
913                         return "<null>";
914                 if (args.Length == 0)
915                         return "<empty>";
916                 return args [index];
917         }
918
919         T GenericMethod<T> (T t)
920         {
921                 return t;
922         }
923
924
925         public static int Main ()
926         {
927                 Tester e = new Tester ();
928                 e.AddTest ();
929                 e.AddStringTest ();
930                 e.AndNullableTest ();
931                 e.AddCheckedTest ();
932                 e.AndTest ();
933                 e.AndAlsoTest ();
934                 e.ArrayIndexTest ();
935                 e.ArrayLengthTest ();
936                 e.CallTest ();
937                 e.CoalesceTest ();
938                 e.ConditionTest ();
939                 e.ConstantTest ();
940                 e.ConvertTest ();
941                 e.ConvertCheckedTest ();
942                 e.DivideTest ();
943                 e.EqualTest ();
944                 e.EqualTestDelegate ();
945                 e.ExclusiveOrTest ();
946                 e.GreaterThanTest ();
947                 e.GreaterThanOrEqualTest ();
948                 e.NewArrayInitTest ();
949                 e.NotTest ();
950                 e.NotNullableTest ();
951                 e.NotEqualTest ();
952                 e.OrTest ();
953                 e.OrNullableTest ();
954                 e.OrElseTest ();
955                 e.ParameterTest ();
956                 e.QuoteTest ();
957                 e.RightShiftTest ();
958
959                 return 0;
960         }
961 }
962