New tests, migrated from errors.
[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 public struct MyType
44 {
45         int value;
46
47         public MyType (int value)
48         {
49                 this.value = value;
50         }
51         
52         public override int GetHashCode ()
53         {
54                 throw new NotImplementedException ();
55         }
56
57         public static implicit operator int (MyType o)
58         {
59                 return o.value;
60         }
61
62         public static bool operator true (MyType a)
63         {
64                 return a.value == a;
65         }
66
67         public static bool operator false (MyType a)
68         {
69                 return a.value != a;
70         }
71
72         public static MyType operator +(MyType a, MyType b)
73         {
74                 return new MyType (a.value + b.value);
75         }
76
77         public static MyType operator / (MyType a, MyType b)
78         {
79                 return new MyType (a.value / b.value);
80         }
81
82         public static MyType operator &(MyType a, MyType b)
83         {
84                 return new MyType (a.value & b.value);
85         }
86
87         public static MyType operator | (MyType a, MyType b)
88         {
89                 return new MyType (a.value | b.value);
90         }
91
92         public static MyType operator ^ (MyType a, MyType b)
93         {
94                 return new MyType (a.value ^ b.value);
95         }
96
97         public static bool operator == (MyType a, MyType b)
98         {
99                 return a.value == b.value;
100         }
101
102         public static bool operator != (MyType a, MyType b)
103         {
104                 return a.value != b.value;
105         }
106         
107         public static bool operator > (MyType a, MyType b)
108         {
109                 return a.value > b.value;
110         }
111
112         public static bool operator < (MyType a, MyType b)
113         {
114                 return a.value < b.value;
115         }
116
117         public static bool operator >= (MyType a, MyType b)
118         {
119                 return a.value >= b.value;
120         }
121         
122         public static bool operator <= (MyType a, MyType b)
123         {
124                 return a.value <= b.value;
125         }
126
127         public static bool operator ! (MyType a)
128         {
129                 return a.value > 0;
130         }
131         
132         public static int operator >> (MyType a, int b)
133         {
134                 return a.value >> b;
135         }       
136
137         public override string ToString ()
138         {
139                 return value.ToString ();
140         }
141 }
142
143 // TODO: Add more nullable tests, follow AddTest pattern.
144
145 class Tester
146 {
147         static void AssertNodeType (LambdaExpression e, ExpressionType et)
148         {
149                 if (e.Body.NodeType != et)
150                         throw new ApplicationException (e.Body.NodeType + " != " + et);
151         }
152
153         static void Assert<T> (T expected, T value)
154         {
155                 if (!EqualityComparer<T>.Default.Equals (expected, value))
156                         throw new ApplicationException (expected + " != " + value);
157         }
158
159         static void Assert<T> (T [] expected, T [] value)
160         {
161                 if (expected.Length != value.Length)
162                         throw new ApplicationException ("Array length does not match " + expected.Length + " != " + value.Length);
163
164                 for (int i = 0; i < expected.Length; ++i) {
165                         if (!EqualityComparer<T>.Default.Equals (expected [i], value [i]))
166                                 throw new ApplicationException ("Index " + i + ": " + expected [i] + " != " + value [i]);
167                 }
168         }
169
170         void AddTest ()
171         {
172                 Expression<Func<int, int, int>> e = (int a, int b) => a + b;
173                 AssertNodeType (e, ExpressionType.Add);
174                 Assert (50, e.Compile ().Invoke (20, 30));
175
176                 Expression<Func<int?, int?, int?>> e2 = (a, b) => a + b;
177                 AssertNodeType (e2, ExpressionType.Add);
178                 Assert (null, e2.Compile ().Invoke (null, 3));
179
180                 Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a + b;
181                 AssertNodeType (e3, ExpressionType.Add);
182                 Assert (10, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
183                 
184                 Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a + b;
185                 AssertNodeType (e4, ExpressionType.Add);
186                 Assert (new MyType (10), e4.Compile ().Invoke (new MyType (-20), new MyType (30)));
187                 Assert (null, e4.Compile ().Invoke (null, new MyType (30)));
188
189                 Expression<Func<int, MyType, int>> e5 = (int a, MyType b) => a + b;
190                 AssertNodeType (e5, ExpressionType.Add);
191                 Assert (31, e5.Compile ().Invoke (1, new MyType (30)));
192 /*
193                 Expression<Func<int, MyType?, int?>> e6 = (int a, MyType? b) => a + b;
194                 AssertNodeType (e6, ExpressionType.Add);
195                 Assert (-1, e6.Compile ().Invoke (-31, new MyType (30)));               
196 */
197         }
198
199         void AddCheckedTest ()
200         {
201                 checked {
202                 Expression<Func<int, int, int>> e = (int a, int b) => a + b;
203                 AssertNodeType (e, ExpressionType.AddChecked);
204                 Assert (50, e.Compile ().Invoke (20, 30));
205
206                 Expression<Func<int?, int?, int?>> e2 = (a, b) => a + b;
207                 AssertNodeType (e2, ExpressionType.AddChecked);
208                 Assert (null, e2.Compile ().Invoke (null, 3));
209
210                 Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a + b;
211                 AssertNodeType (e3, ExpressionType.Add);
212                 Assert (10, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
213                 }
214         }
215
216         void AndTest ()
217         {
218                 Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a & b;
219
220                 AssertNodeType (e, ExpressionType.And);
221                 Func<bool, bool, bool> c = e.Compile ();
222
223                 Assert (true, c (true, true));
224                 Assert (false, c (true, false));
225                 Assert (false, c (false, true));
226                 Assert (false, c (false, false));
227
228                 Expression<Func<MyType, MyType, MyType>> e2 = (MyType a, MyType b) => a & b;
229
230                 AssertNodeType (e2, ExpressionType.And);
231                 var c2 = e2.Compile ();
232
233                 Assert (new MyType (0), c2 (new MyType (0), new MyType (1)));
234                 Assert (new MyType (1), c2 (new MyType (0xFF), new MyType (0x01)));
235         }
236
237         void AndNullableTest ()
238         {
239                 Expression<Func<bool?, bool?, bool?>> e = (bool? a, bool? b) => a & b;
240
241                 AssertNodeType (e, ExpressionType.And);
242                 Func<bool?, bool?, bool?> c = e.Compile ();
243
244                 Assert (true, c (true, true));
245                 Assert (false, c (true, false));
246                 Assert (false, c (false, true));
247                 Assert (false, c (false, false));
248
249                 Assert (null, c (true, null));
250                 Assert (false, c (false, null));
251                 Assert (false, c (null, false));
252                 Assert (null, c (true, null));
253                 Assert (null, c (null, null));
254
255                 Expression<Func<MyType?, MyType?, MyType?>> e2 = (MyType? a, MyType? b) => a & b;
256
257                 AssertNodeType (e2, ExpressionType.And);
258                 var c2 = e2.Compile ();
259
260                 Assert (new MyType (0), c2 (new MyType (0), new MyType (1)));
261                 Assert (new MyType (1), c2 (new MyType (0xFF), new MyType (0x01)));
262                 Assert (null, c2 (new MyType (0xFF), null));
263         }
264
265         void AndAlsoTest ()
266         {
267                 Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a && b;
268
269                 AssertNodeType (e, ExpressionType.AndAlso);
270                 Assert (false, e.Compile ().Invoke (true, false));
271
272                 Expression<Func<MyType, MyType, MyType>> e2 = (MyType a, MyType b) => a && b;
273
274                 AssertNodeType (e2, ExpressionType.AndAlso);
275                 Assert (new MyType (64), e2.Compile ().Invoke (new MyType (64), new MyType (64)));
276                 Assert (new MyType (0), e2.Compile ().Invoke (new MyType (32), new MyType (64)));
277         }
278
279         void ArrayIndexTest ()
280         {
281                 Expression<Func<string [], long, string>> e = (string [] a, long i) => a [i];
282                 AssertNodeType (e, ExpressionType.ArrayIndex);
283                 Assert ("b", e.Compile ().Invoke (new string [] { "a", "b", "c" }, 1));
284
285                 Expression<Func<string [], string>> e2 = (string [] a) => a [0];
286                 AssertNodeType (e2, ExpressionType.ArrayIndex);
287                 Assert ("a", e2.Compile ().Invoke (new string [] { "a", "b" }));
288
289                 Expression<Func<object [,], int, int, object>> e3 = (object [,] a, int i, int j) => a [i, j];
290                 AssertNodeType (e3, ExpressionType.Call);
291
292                 Assert ("z", e3.Compile ().Invoke (
293                         new object [,] { { 1, 2 }, { "x", "z" } }, 1, 1));
294
295                 Expression<Func<decimal [] [], byte, decimal>> e4 = (decimal [] [] a, byte b) => a [b] [1];
296                 AssertNodeType (e4, ExpressionType.ArrayIndex);
297
298                 decimal [] [] array = { new decimal [] { 1, 9 }, new decimal [] { 10, 90 } };
299                 Assert (90, e4.Compile ().Invoke (array, 1));
300         }
301
302         void ArrayLengthTest ()
303         {
304                 Expression<Func<double [], int>> e = (double [] a) => a.Length;
305                 AssertNodeType (e, ExpressionType.ArrayLength);
306                 Assert (0, e.Compile ().Invoke (new double [0]));
307                 Assert (9, e.Compile ().Invoke (new double [9]));
308
309                 // TODO: implement
310                 //Expression<Func<string [,], int>> e2 = (string [,] a) => a.Length;
311                 //AssertNodeType (e2, ExpressionType.MemberAccess);
312                 //Assert (0, e2.Compile ().Invoke (new string [0, 0]));
313         }
314
315         void CallTest ()
316         {
317                 Expression<Func<int, int>> e = (int a) => Math.Max (a, 5);
318                 AssertNodeType (e, ExpressionType.Call);
319                 Assert (5, e.Compile ().Invoke (2));
320                 Assert (9, e.Compile ().Invoke (9));
321
322                 Expression<Func<string, string>> e2 = (string a) => InstanceMethod (a);
323                 AssertNodeType (e2, ExpressionType.Call);
324                 Assert ("abc", e2.Compile ().Invoke ("abc"));
325
326                 Expression<Func<int, string, int, object>> e3 = (int index, string a, int b) => InstanceParamsMethod (index, a, b);
327                 AssertNodeType (e3, ExpressionType.Call);
328                 Assert<object> (4, e3.Compile ().Invoke (1, "a", 4));
329
330                 Expression<Func<object>> e4 = () => InstanceParamsMethod (0);
331                 AssertNodeType (e4, ExpressionType.Call);
332                 Assert<object> ("<empty>", e4.Compile ().Invoke ());
333
334                 Expression<Func<int, int>> e5 = (int a) => GenericMethod (a);
335                 AssertNodeType (e5, ExpressionType.Call);
336                 Assert (5, e5.Compile ().Invoke (5));
337         }
338
339         void CoalesceTest ()
340         {
341                 Expression<Func<uint?, uint>> e = (uint? a) => a ?? 99;
342                 AssertNodeType (e, ExpressionType.Coalesce);
343                 var r = e.Compile ();
344                 Assert ((uint) 5, r.Invoke (5));
345                 Assert ((uint) 99, r.Invoke (null));
346
347                 Expression<Func<MyType?, int>> e2 = (MyType? a) => a ?? -3;
348                 AssertNodeType (e2, ExpressionType.Coalesce);
349                 var r2 = e2.Compile ();
350                 Assert (2, r2.Invoke (new MyType (2)));
351                 Assert (-3, r2.Invoke (null));
352         }
353
354         void ConditionTest ()
355         {
356                 Expression<Func<bool, byte, int, int>> e = (bool a, byte b, int c) => (a ? b : c);
357                 AssertNodeType (e, ExpressionType.Conditional);
358                 var r = e.Compile ();
359                 Assert (3, r.Invoke (true, 3, 999999));
360                 Assert (999999, r.Invoke (false, 3, 999999));
361
362                 Expression<Func<int, decimal, decimal?>> e2 = (int a, decimal d) => (a > 0 ? d : a < 0 ? -d : (decimal?) null);
363                 AssertNodeType (e2, ExpressionType.Conditional);
364                 var r2 = e2.Compile ();
365                 Assert (null, r2.Invoke (0, 10));
366                 Assert (50, r2.Invoke (1, 50));
367                 Assert (30, r2.Invoke (-7, -30));
368
369                 Expression<Func<bool?, int?>> e3 = (bool? a) => ((bool) a ? 3 : -2);
370                 AssertNodeType (e3, ExpressionType.Convert);
371                 var r3 = e3.Compile ();
372                 Assert (3, r3.Invoke (true));
373                 Assert (-2, r3.Invoke (false));
374
375                 Expression<Func<InverseLogicalOperator, byte, byte, byte>> e4 = (InverseLogicalOperator a, byte b, byte c) => (a ? b : c);
376                 AssertNodeType (e4, ExpressionType.Conditional);
377                 var r4 = e4.Compile ();
378                 Assert (3, r4.Invoke (new InverseLogicalOperator (true), 3, 4));
379                 Assert (4, r4.Invoke (new InverseLogicalOperator (false), 3, 4));
380         }
381
382         void ConvertTest ()
383         {
384                 Expression<Func<int, byte>> e = (int a) => ((byte) a);
385                 AssertNodeType (e, ExpressionType.Convert);
386                 Assert (100, e.Compile ().Invoke (100));
387
388                 Expression<Func<long, ushort>> e2 = (long a) => ((ushort) a);
389                 AssertNodeType (e2, ExpressionType.Convert);
390                 Assert (100, e2.Compile ().Invoke (100));
391
392                 Expression<Func<float?, float>> e3 = (float? a) => ((float) a);
393                 AssertNodeType (e3, ExpressionType.Convert);
394                 Assert (-0.456f, e3.Compile ().Invoke (-0.456f));
395
396                 Expression<Func<MyType, int>> e4 = (MyType a) => (a);
397                 AssertNodeType (e4, ExpressionType.Convert);
398                 Assert (-9, e4.Compile ().Invoke (new MyType (-9)));
399
400                 Expression<Func<MyType, MyType, bool?>> e5 = (MyType a, MyType b) => a == b;
401                 AssertNodeType (e5, ExpressionType.Convert);
402         }
403
404         void ConvertCheckedTest ()
405         {
406                 Expression<Func<int, byte>> e = (int a) => checked((byte) a);
407                 AssertNodeType (e, ExpressionType.ConvertChecked);
408                 Assert (100, e.Compile ().Invoke (100));
409
410                 checked {
411                         Expression<Func<long, ushort>> e2 = (long a) => unchecked((ushort) a);
412                         AssertNodeType (e2, ExpressionType.Convert);
413                         Assert (100, e2.Compile ().Invoke (100));
414
415                         Expression<Func<float?, float>> e3 = (float? a) => ((float) a);
416                         AssertNodeType (e3, ExpressionType.ConvertChecked);
417                         Assert (-0.456f, e3.Compile ().Invoke (-0.456f));
418
419                         Expression<Func<MyType, int>> e4 = (MyType a) => (a);
420                         AssertNodeType (e4, ExpressionType.Convert);
421                         Assert (-9, e4.Compile ().Invoke (new MyType (-9)));
422                 }
423         }
424
425         void DivideTest ()
426         {
427                 Expression<Func<int, int, int>> e = (int a, int b) => a / b;
428                 AssertNodeType (e, ExpressionType.Divide);
429                 Assert (2, e.Compile ().Invoke (60, 30));
430
431                 Expression<Func<double?, double?, double?>> e2 = (a, b) => a / b;
432                 AssertNodeType (e2, ExpressionType.Divide);
433                 Assert (null, e2.Compile ().Invoke (null, 3));
434                 Assert (1.5, e2.Compile ().Invoke (3, 2));
435
436                 Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a / b;
437                 AssertNodeType (e3, ExpressionType.Divide);
438                 Assert (1, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
439
440                 Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a / b;
441                 AssertNodeType (e4, ExpressionType.Divide);
442                 Assert (null, e4.Compile ().Invoke (null, new MyType (-20)));
443                 Assert (new MyType (-6), e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
444         }
445
446         void EqualTest ()
447         {
448                 Expression<Func<int, int, bool>> e = (int a, int b) => a == b;
449                 AssertNodeType (e, ExpressionType.Equal);
450                 Assert (false, e.Compile ().Invoke (60, 30));
451                 Assert (true, e.Compile ().Invoke (-1, -1));
452
453                 Expression<Func<double?, double?, bool>> e2 = (a, b) => a == b;
454                 AssertNodeType (e2, ExpressionType.Equal);
455                 Assert (true, e2.Compile ().Invoke (3, 3));
456                 Assert (false, e2.Compile ().Invoke (3, 2));
457
458                 Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a == b;
459                 AssertNodeType (e3, ExpressionType.Equal);
460                 Assert (true, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
461
462                 Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a == b;
463                 AssertNodeType (e4, ExpressionType.Equal);
464                 Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
465                 Assert (true, e4.Compile ().Invoke (null, null));
466                 Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (120)));
467         }
468         
469         delegate void EmptyDelegate ();
470         
471         void EqualTestDelegate ()
472         {
473                 Expression<Func<Delegate, Delegate, bool>> e1 = (a, b) => a == b;
474                 AssertNodeType (e1, ExpressionType.Equal);
475                 Assert (true, e1.Compile ().Invoke (null, null));
476
477                 EmptyDelegate ed = delegate () {};
478
479                 Expression<Func<EmptyDelegate, EmptyDelegate, bool>> e2 = (a, b) => a == b;
480                 AssertNodeType (e2, ExpressionType.Equal);
481                 Assert (false, e2.Compile ().Invoke (delegate () {}, null));
482                 Assert (false, e2.Compile ().Invoke (delegate () {}, delegate {}));
483                 Assert (false, e2.Compile ().Invoke (ed, delegate {}));
484                 Assert (true, e2.Compile ().Invoke (ed, ed));
485         }       
486
487         void ExclusiveOrTest ()
488         {
489                 Expression<Func<int, int, int>> e = (int a, int b) => a ^ b;
490                 AssertNodeType (e, ExpressionType.ExclusiveOr);
491                 Assert (34, e.Compile ().Invoke (60, 30));
492 /* FIXME: missing conversion
493                 Expression<Func<byte?, byte?, int?>> e2 = (a, b) => a ^ b;
494                 AssertNodeType (e2, ExpressionType.ExclusiveOr);
495                 Assert (null, e2.Compile ().Invoke (null, 3));
496                 Assert (1, e2.Compile ().Invoke (3, 2));
497 */
498                 Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a ^ b;
499                 AssertNodeType (e3, ExpressionType.ExclusiveOr);
500                 Assert (0, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
501
502                 Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a ^ b;
503                 AssertNodeType (e4, ExpressionType.ExclusiveOr);
504                 Assert (null, e4.Compile ().Invoke (null, new MyType (-20)));
505                 Assert (new MyType (-108), e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
506         }
507
508         void GreaterThanTest ()
509         {
510                 Expression<Func<int, int, bool>> e = (int a, int b) => a > b;
511                 AssertNodeType (e, ExpressionType.GreaterThan);
512                 Assert (true, e.Compile ().Invoke (60, 30));
513 /*
514                 Expression<Func<uint?, byte?, bool>> e2 = (a, b) => a > b;
515                 AssertNodeType (e2, ExpressionType.GreaterThan);
516                 Assert (false, e2.Compile ().Invoke (null, 3));
517                 Assert (false, e2.Compile ().Invoke (2, 2));
518
519                 Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a > b;
520                 AssertNodeType (e3, ExpressionType.GreaterThan);
521                 Assert (false, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
522
523                 Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a > b;
524                 AssertNodeType (e4, ExpressionType.GreaterThan);
525                 Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
526                 Assert (false, e4.Compile ().Invoke (null, null));
527                 Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
528 */
529         }
530
531         void GreaterThanOrEqualTest ()
532         {
533                 Expression<Func<int, int, bool>> e = (int a, int b) => a >= b;
534                 AssertNodeType (e, ExpressionType.GreaterThanOrEqual);
535                 Assert (true, e.Compile ().Invoke (60, 30));
536
537                 Expression<Func<byte?, byte?, bool>> e2 = (a, b) => a >= b;
538                 AssertNodeType (e2, ExpressionType.GreaterThanOrEqual);
539                 Assert (false, e2.Compile ().Invoke (null, 3));
540                 Assert (true, e2.Compile ().Invoke (2, 2));
541
542                 Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a >= b;
543                 AssertNodeType (e3, ExpressionType.GreaterThanOrEqual);
544                 Assert (true, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
545 /*
546                 Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a >= null;
547                 AssertNodeType (e4, ExpressionType.GreaterThanOrEqual);
548                 Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
549                 Assert (false, e4.Compile ().Invoke (null, null));
550                 Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
551 */
552         }
553
554         void NewArrayInitTest ()
555         {
556                 Expression<Func<int []>> e = () => new int [0];
557                 AssertNodeType (e, ExpressionType.NewArrayInit);
558                 Assert (new int [0], e.Compile ().Invoke ());
559
560                 e = () => new int [] { };
561                 AssertNodeType (e, ExpressionType.NewArrayInit);
562                 Assert (new int [0], e.Compile ().Invoke ());
563
564                 Expression<Func<ushort, ulong? []>> e2 = (ushort a) => new ulong? [] { a };
565                 AssertNodeType (e2, ExpressionType.NewArrayInit);
566                 Assert (new ulong? [1] { ushort.MaxValue }, e2.Compile ().Invoke (ushort.MaxValue));
567
568                 Expression<Func<char [] []>> e3 = () => new char [] [] { new char [] { 'a' } };
569                 AssertNodeType (e3, ExpressionType.NewArrayInit);
570                 Assert (new char [] { 'a' }, e3.Compile ().Invoke () [0]);
571         }
572         
573         void NotTest ()
574         {
575                 Expression<Func<bool, bool>> e = (bool a) => !a;
576                 AssertNodeType (e, ExpressionType.Not);
577                 Assert (false, e.Compile ().Invoke (true));
578
579                 Expression<Func<MyType, bool>> e2 = (MyType a) => !a;
580                 AssertNodeType (e2, ExpressionType.Not);
581                 Assert (true, e2.Compile ().Invoke (new MyType (1)));
582                 Assert (false, e2.Compile ().Invoke (new MyType (-1)));
583         }
584
585         void NotNullableTest ()
586         {
587                 Expression<Func<bool?, bool?>> e = (bool? a) => !a;
588                 AssertNodeType (e, ExpressionType.Not);
589                 Assert (false, e.Compile ().Invoke (true));
590                 Assert (null, e.Compile ().Invoke (null));
591
592                 Expression<Func<MyType?, bool?>> e2 = (MyType? a) => !a;
593                 AssertNodeType (e2, ExpressionType.Not);
594                 Assert (true, e2.Compile ().Invoke (new MyType (1)));
595                 Assert (null, e2.Compile ().Invoke (null));
596         }
597         
598         void NotEqualTest ()
599         {
600                 Expression<Func<int, int, bool>> e = (int a, int b) => a != b;
601                 AssertNodeType (e, ExpressionType.NotEqual);
602                 Assert (true, e.Compile ().Invoke (60, 30));
603                 Assert (false, e.Compile ().Invoke (-1, -1));
604
605                 Expression<Func<sbyte?, sbyte?, bool>> e2 = (a, b) => a != b;
606                 AssertNodeType (e2, ExpressionType.NotEqual);
607                 Assert (false, e2.Compile ().Invoke (3, 3));
608                 Assert (true, e2.Compile ().Invoke (3, 2));
609
610                 Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a != b;
611                 AssertNodeType (e3, ExpressionType.NotEqual);
612                 Assert (false, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
613
614                 Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a != b;
615                 AssertNodeType (e4, ExpressionType.NotEqual);
616                 Assert (true, e4.Compile ().Invoke (null, new MyType (-20)));
617                 Assert (false, e4.Compile ().Invoke (null, null));
618                 Assert (false, e4.Compile ().Invoke (new MyType (120), new MyType (120)));
619         }       
620
621         void OrTest ()
622         {
623                 Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a | b;
624
625                 AssertNodeType (e, ExpressionType.Or);
626                 Func<bool, bool, bool> c = e.Compile ();
627
628                 Assert (true, c (true, true));
629                 Assert (true, c (true, false));
630                 Assert (true, c (false, true));
631                 Assert (false, c (false, false));
632
633                 Expression<Func<MyType, MyType, MyType>> e2 = (MyType a, MyType b) => a | b;
634                 AssertNodeType (e2, ExpressionType.Or);
635                 var c2 = e2.Compile ();
636                 Assert (new MyType (3), c2 (new MyType (1), new MyType (2)));
637         }
638
639         void OrNullableTest ()
640         {
641                 Expression<Func<bool?, bool?, bool?>> e = (bool? a, bool? b) => a | b;
642
643                 AssertNodeType (e, ExpressionType.Or);
644                 Func<bool?, bool?, bool?> c = e.Compile ();
645
646                 Assert (true, c (true, true));
647                 Assert (true, c (true, false));
648                 Assert (true, c (false, true));
649                 Assert (false, c (false, false));
650
651                 Assert (true, c (true, null));
652                 Assert (null, c (false, null));
653                 Assert (null, c (null, false));
654                 Assert (true, c (true, null));
655                 Assert (null, c (null, null));
656
657                 Expression<Func<MyType?, MyType?, MyType?>> e2 = (MyType? a, MyType? b) => a | b;
658                 AssertNodeType (e2, ExpressionType.Or);
659                 var c2 = e2.Compile ();
660                 Assert (new MyType (3), c2 (new MyType (1), new MyType (2)));
661                 Assert (null, c2 (new MyType (1), null));
662         }
663         
664         void OrElseTest ()
665         {
666                 Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a || b;
667                 AssertNodeType (e, ExpressionType.OrElse);
668                 Assert (true, e.Compile ().Invoke (true, false));
669
670                 Expression<Func<MyType, MyType, MyType>> e2 = (MyType a, MyType b) => a || b;
671                 AssertNodeType (e2, ExpressionType.OrElse);
672                 Assert (new MyType (64), e2.Compile ().Invoke (new MyType (64), new MyType (64)));
673                 Assert (new MyType (32), e2.Compile ().Invoke (new MyType (32), new MyType (64)));
674         }
675         
676         void ParameterTest ()
677         {
678                 Expression<Func<string, string>> e = (string a) => a;
679                 AssertNodeType (e, ExpressionType.Parameter);
680                 Assert ("t", e.Compile ().Invoke ("t"));
681
682                 Expression<Func<object[], object[]>> e2 = (object[] a) => a;
683                 AssertNodeType (e2, ExpressionType.Parameter);
684                 Assert (new object[0], e2.Compile ().Invoke (new object[0]));
685
686                 Expression<Func<IntPtr, IntPtr>> e3 = a => a;
687                 AssertNodeType (e3, ExpressionType.Parameter);
688                 Assert (IntPtr.Zero, e3.Compile ().Invoke (IntPtr.Zero));
689         }
690         
691         void QuoteTest ()
692         {
693                 Expression<Func<Expression<Func<int>>>> e = () => () => 2;
694                 AssertNodeType (e, ExpressionType.Quote);
695                 Assert (2, e.Compile ().Invoke ().Compile ().Invoke ());
696         }
697
698         void RightShiftTest ()
699         {
700                 Expression<Func<ulong, short, ulong>> e = (ulong a, short b) => a >> b;
701                 AssertNodeType (e, ExpressionType.RightShift);
702                 Assert ((ulong)0x1FD940L, e.Compile ().Invoke (0xFECA0000, 11));
703                 Assert ((ulong)0, e.Compile ().Invoke (0xFFFFFFFF, 0xA01));
704
705                 Expression<Func<MyType, MyType, int>> e2 = (MyType a, MyType b) => a >> b;
706                 AssertNodeType (e2, ExpressionType.RightShift);
707                 var c2 = e2.Compile ();
708                 Assert (64, c2 (new MyType (256), new MyType (2)));
709                 
710                 Expression<Func<long?, sbyte, long?>> e3 = (long? a, sbyte b) => a >> b;
711                 AssertNodeType (e3, ExpressionType.RightShift);
712                 Assert (null, e3.Compile ().Invoke (null, 11));
713                 Assert (512, e3.Compile ().Invoke (1024, 1));
714
715                 Expression<Func<MyType?, MyType?, int?>> e4 = (MyType? a, MyType? b) => a >> b;
716                 AssertNodeType (e4, ExpressionType.RightShift);
717                 var c4 = e4.Compile ();
718                 Assert (null, c4 (new MyType (8), null));
719                 Assert (null, c4 (null, new MyType (8)));
720                 Assert (64, c4 (new MyType (256), new MyType (2)));
721         }       
722
723         //
724         // Test helpers
725         //
726         string InstanceMethod (string arg)
727         {
728                 return arg;
729         }
730
731         object InstanceParamsMethod (int index, params object [] args)
732         {
733                 if (args == null)
734                         return "<null>";
735                 if (args.Length == 0)
736                         return "<empty>";
737                 return args [index];
738         }
739
740         T GenericMethod<T> (T t)
741         {
742                 return t;
743         }
744
745
746         public static int Main ()
747         {
748                 Tester e = new Tester ();
749                 e.AddTest ();
750                 e.AndNullableTest ();
751                 e.AddCheckedTest ();
752                 e.AndTest ();
753                 e.AndAlsoTest ();
754                 e.ArrayIndexTest ();
755                 e.ArrayLengthTest ();
756                 e.CallTest ();
757                 e.CoalesceTest ();
758                 e.ConditionTest ();
759                 e.ConvertTest ();
760                 e.ConvertCheckedTest ();
761                 e.DivideTest ();
762                 e.EqualTest ();
763                 e.EqualTestDelegate ();
764                 e.ExclusiveOrTest ();
765                 e.GreaterThanTest ();
766                 e.GreaterThanOrEqualTest ();
767                 e.NewArrayInitTest ();
768                 e.NotTest ();
769                 e.NotNullableTest ();
770                 e.NotEqualTest ();
771                 e.OrTest ();
772                 e.OrNullableTest ();
773                 e.OrElseTest ();
774                 e.ParameterTest ();
775                 e.QuoteTest ();
776                 e.RightShiftTest ();
777
778                 return 0;
779         }
780 }
781