Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / tests / dtest-006.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection;
5
6 // Dynamic binary operator, unary operators and convert tests
7
8 public struct InverseLogicalOperator
9 {
10         bool value;
11         public InverseLogicalOperator (bool value)
12         {
13                 this.value = value;
14         }
15
16         public static bool operator true (InverseLogicalOperator u)
17         {
18                 return u.value;
19         }
20
21         public static bool operator false (InverseLogicalOperator u)
22         {
23                 return u.value;
24         }
25 }
26
27 public struct MyType
28 {
29         int value;
30         
31         public MyType (int value) : this ()
32         {
33                 this.value = value;
34         }
35         
36         public short ShortProp { get; set; }
37         
38         public override int GetHashCode ()
39         {
40                 throw new NotImplementedException ();
41         }
42
43         public static bool operator true (MyType a)
44         {
45                 return a.value != 1;
46         }
47
48         public static bool operator false (MyType a)
49         {
50                 return a.value == 0;
51         }
52
53         public static MyType operator + (MyType a, MyType b)
54         {
55                 return new MyType (a.value + b.value);
56         }
57
58         public static MyType operator - (MyType a, MyType b)
59         {
60                 return new MyType (a.value - b.value);
61         }
62
63         public static MyType operator / (MyType a, MyType b)
64         {
65                 return new MyType (a.value / b.value);
66         }
67
68         public static MyType operator * (MyType a, MyType b)
69         {
70                 return new MyType (a.value * b.value);
71         }
72
73         public static MyType operator % (MyType a, MyType b)
74         {
75                 return new MyType (a.value % b.value);
76         }
77
78         public static MyType operator &(MyType a, MyType b)
79         {
80                 return new MyType (a.value & b.value);
81         }
82
83         public static MyType operator | (MyType a, MyType b)
84         {
85                 return new MyType (a.value | b.value);
86         }
87
88         public static MyType operator ^ (MyType a, MyType b)
89         {
90                 return new MyType (a.value ^ b.value);
91         }
92
93         public static bool operator == (MyType a, MyType b)
94         {
95                 return a.value == b.value;
96         }
97
98         public static bool operator != (MyType a, MyType b)
99         {
100                 return a.value != b.value;
101         }
102         
103         public static bool operator > (MyType a, MyType b)
104         {
105                 return a.value > b.value;
106         }
107
108         public static bool operator < (MyType a, MyType b)
109         {
110                 return a.value < b.value;
111         }
112
113         public static bool operator >= (MyType a, MyType b)
114         {
115                 return a.value >= b.value;
116         }
117         
118         public static bool operator <= (MyType a, MyType b)
119         {
120                 return a.value <= b.value;
121         }
122
123         public static bool operator ! (MyType a)
124         {
125                 return a.value > 0;
126         }
127
128         public static int operator ~ (MyType a)
129         {
130                 return ~a.value;
131         }
132
133         public static MyType operator ++ (MyType a)
134         {
135                 return new MyType (a.value * 2);
136         }
137
138         public static MyType operator -- (MyType a)
139         {
140                 return new MyType (a.value / 2);
141         }
142
143         public static int operator >> (MyType a, int b)
144         {
145                 return a.value >> b;
146         }
147         
148         public static int operator << (MyType a, int b)
149         {
150                 return a.value << b;
151         }
152         
153         public static MyType operator - (MyType a)
154         {
155                 return new MyType (-a.value);
156         }
157         
158         public static MyType operator + (MyType a)
159         {
160                 return new MyType (334455); // magic number
161         }
162
163         public override string ToString ()
164         {
165                 return value.ToString ();
166         }
167 }
168
169
170 class MyTypeExplicit
171 {
172         int value;
173         
174         public MyTypeExplicit (int value)
175         {
176                 this.value = value;
177         }
178         
179         public static explicit operator int (MyTypeExplicit m)
180         {
181                 return m.value;
182         }
183 }
184
185 struct MyTypeImplicitOnly
186 {
187         short b;
188
189         public MyTypeImplicitOnly (short b)
190         {
191                 this.b = b;
192         }
193
194         public static implicit operator short (MyTypeImplicitOnly m)
195         {
196                 return m.b;
197         }
198
199         public static implicit operator bool (MyTypeImplicitOnly m)
200         {
201                 return m.b != 0;
202         }
203 }
204
205 enum MyEnum : byte
206 {
207         Value_1 = 1,
208         Value_2 = 2
209 }
210
211 enum MyEnumUlong : ulong
212 {
213         Value_1 = 1,
214         Value_2 = 2
215 }
216
217
218 class Tester
219 {
220         delegate void EmptyDelegate ();
221         event Action ev_assign;
222
223         static void Assert<T> (T expected, T value, string name)
224         {
225                 if (!EqualityComparer<T>.Default.Equals (expected, value)) {
226                         name += ": ";
227                         throw new ApplicationException (name + expected + " != " + value);
228                 }
229         }
230
231         static void AssertChecked<T> (Func<T> expected, T value, string name)
232         {
233                 try {
234                         Assert (expected (), value, name);
235                         throw new ApplicationException (name + ": OverflowException expected");
236                 } catch (OverflowException) {
237                         // passed
238                 }
239         }
240
241         static void AssertChecked (Action expected, string name)
242         {
243                 try {
244                         expected ();
245                         throw new ApplicationException (name + ": OverflowException expected");
246                 } catch (OverflowException) {
247                         // passed
248                 }
249         }
250
251 #pragma warning disable 169
252
253         void AddTest ()
254         {
255                 dynamic d = 5;
256
257                 int v = 2;
258                 Assert (d + v, 7, "#1");
259                 double v2 = 0.5;
260                 Assert (d + v2, 5.5, "#1a");
261
262                 d = new MyType (5);
263                 MyType v3 = new MyType (30);
264                 Assert (d + v3, new MyType (35), "#3");
265                 dynamic d3 = new MyType (-7);
266                 Assert<MyType> (d3 + new MyType (6), new MyType (-1), "#3a");
267
268                 d3 = new MyTypeImplicitOnly (6);
269                 Assert (d3 + new MyTypeImplicitOnly (11), 17, "#3b");
270
271                 d = new MyTypeImplicitOnly (5);
272                 decimal v4 = 4m;
273                 Assert (d + v4, 9m, "#4");
274         }
275
276         void AddNullableTest ()
277         {
278                 dynamic d = 5;
279
280                 int? v2 = null;
281                 Assert<int?> (d + v2, null, "#1");
282                 Assert<int?> (d + null, null, "#1a");
283                 Assert<int?> (null + d, null, "#1b");
284
285                 v2 = -2;
286                 Assert (d + v2, 3, "#2");
287                 dynamic d2 = (int?) -2;
288                 Assert (d2 + 1, -1, "#2a");
289
290                 d = new MyType (5);
291                 MyType? v3 = new MyType (30);
292                 Assert (d + v3, new MyType (35), "#3");
293                 dynamic d3 = new MyType? (new MyType (-7));
294                 Assert (d3 + new MyType (6), new MyType (-1), "#3a");
295                 Assert<MyType?> (d3 + null, null, "#3b");
296
297                 d = new MyTypeImplicitOnly (5);
298                 decimal? v4 = 4m;
299                 Assert (d + v4, 9m, "#4");
300                 v4 = null;
301                 Assert<decimal?> (d + v4, null, "#4a");
302         }
303         
304         void AddEnumTest ()
305         {
306                 dynamic d = MyEnum.Value_1;
307
308                 Assert (d + 1, MyEnum.Value_2, "#1");
309
310                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
311                 Assert (d2 + (byte) 1, MyEnumUlong.Value_2, "#2");
312                 Assert<MyEnumUlong?> (d2 + null, null, "#2a");
313                 
314                 // CSC: Invalid System.InvalidOperationException
315                 Assert<MyEnum?> (d + null, null, "#1");
316         }
317         
318         void AddCheckedTest ()
319         {
320                 checked {
321                         dynamic d = 5;
322
323                         int v = int.MaxValue;
324                         AssertChecked (() => d + v, 7, "#1");
325
326                         int? v2 = v;
327                         AssertChecked (() => d + v2, null, "#2");
328
329                         d = new MyType (3);
330                         MyType v3 = new MyType (int.MaxValue);
331                         Assert (new MyType (-2147483646), d + v3, "#3");
332                 }
333         }
334         
335         void AddStringTest ()
336         {
337                 dynamic d = "foo";
338                 string v = "->";
339                 Assert (d + v, "foo->", "#1");
340                 Assert (d + 1, "foo1", "#1a");
341                 Assert (d + null, "foo", "#1b");
342                 Assert (d + 1 + v, "foo1->", "#1a");
343
344                 uint? v2 = 4;
345                 Assert (d + v2, "foo4", "#2");
346         }
347
348         void AddAssignTest ()
349         {
350                 dynamic d = 5;
351
352                 int v = 2;
353                 d += v;
354                 Assert (d, 7, "#1");
355
356                 d = 5.0;
357                 double v2 = 0.5;
358                 d += v2;
359                 Assert (d, 5.5, "#1a");
360                 d += v;
361                 Assert (d, 7.5, "#1b");
362
363                 dynamic d3 = new MyType (-7);
364                 d3 += new MyType (6);
365                 Assert<MyType> (d3, new MyType (-1), "#3");
366
367                 d = 5m;
368                 decimal v4 = 4m;
369                 d += v4;
370                 Assert (d, 9m, "#4");
371         }
372
373         void AddAssignNullableTest ()
374         {
375                 dynamic d = (int?) 5;
376
377                 // FEATURE
378                 // For now it's impossible to use nullable compound assignment
379                 // due to the way how DLR works. GetType () on nullable object returns
380                 // underlying type and not nullable type, that means that
381                 // C# binder is initialized with wrong operand type and any operation
382                 // fails to resolve
383 /*
384                 long? v2 = null;
385                 d += v2;
386                 Assert<int?> (d, null, "#1");
387                 d += null;
388                 Assert<int?> (d, null, "#1a");
389
390                 long? l = (long?) 3;
391                 d = l;
392                 v2 = -2;
393                 d += v2;
394                 Assert (d, 3, "#2");
395                 d = (int?) -2;
396                 d += 1;
397                 Assert (d, -1, "#2a");
398
399                 MyType? v3 = new MyType (30);
400                 d += v3;
401                 Assert (d, new MyType (35), "#3");
402                 dynamic d3 = new MyType? (new MyType (-7));
403                 Assert (d3 + new MyType (6), new MyType (-1), "#3a");
404                 Assert<MyType?> (d3 + null, null, "#3b");
405
406                 decimal? v4 = 4m;
407                 d = 2m;
408                 d += v4;
409                 Assert (d, 9m, "#4");
410                 d += null;
411                 Assert<decimal?> (d, null, "#4a");
412  */
413         }
414
415         void AddAssignEnumTest ()
416         {
417                 dynamic d = MyEnum.Value_1;
418
419                 d = MyEnum.Value_1;
420                 d += 1;
421                 Assert (d, MyEnum.Value_2, "#2");
422
423                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
424                 d2 += (byte) 1;
425                 Assert (d2, MyEnumUlong.Value_2, "#3");
426         }
427
428         void AddAssignCheckedTest ()
429         {
430                 checked {
431                         dynamic d = 5;
432
433                         int v = int.MaxValue;
434                         AssertChecked (() => { d += v; Assert (d, 0, "#1-"); }, "#1");
435
436                         d = new MyType (5);
437                         MyType v3 = new MyType (int.MaxValue);
438                         d += v3;
439                         Assert (d, new MyType (-2147483644), "#3-");
440                 }
441         }
442
443         void AddAssignStringTest ()
444         {
445                 dynamic d = "foo";
446                 string v = "->";
447                 d += v;
448                 Assert (d, "foo->", "#1");
449
450                 d = "foo";
451                 d += 1;
452                 Assert (d, "foo1", "#1a");
453
454                 d += null;
455                 Assert (d, "foo1", "#1b");
456
457                 uint? v2 = 4;
458                 d = "foo";
459                 d += v2;
460                 Assert (d, "foo4", "#2");
461         }
462
463         void AddAssignEvent ()
464         {
465                 dynamic d = null;
466                 
467                 // FIXME: Will have to special case events
468                 // ev_assign += d;
469         }
470
471         void AndTest ()
472         {
473                 dynamic d = true;
474
475                 var v = false;
476                 Assert (d & v, false, "#1");
477                 Assert (d & true, true, "#1a");
478
479                 d = 42;
480                 var v2 = 62;
481                 Assert (d & v2, 42, "#2");
482                 Assert (d & 0, 0, "#2a");
483
484                 d = new MyType (10);
485                 MyType v3 = new MyType (30);
486                 Assert (d & v3, new MyType (10), "#3");
487                 dynamic d3 = new MyType (-7);
488                 Assert<MyType> (d3 & new MyType (6), new MyType (0), "#3a");
489
490                 d3 = new MyTypeImplicitOnly (6);
491                 Assert (d3 & 11, 2, "#3b");
492         }
493
494         void AndTestEnum ()
495         {
496                 dynamic d = MyEnum.Value_1;
497
498                 Assert<MyEnum?> (d & null, null, "#1");
499
500                 Assert (d & d, MyEnum.Value_1, "#2");
501
502                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
503                 Assert<MyEnumUlong> (d2 & MyEnumUlong.Value_2, 0, "#3");
504         }
505
506         void AndTestNullable ()
507         {
508                 dynamic d = 5;
509
510                 int? v2 = null;
511                 Assert<int?> (d & v2, null, "#1");
512                 Assert<int?> (d & null, null, "#1a");
513                 Assert<int?> (null & d, null, "#1b");
514
515                 v2 = -2;
516                 Assert (d & v2, 4, "#2");
517                 dynamic d2 = (int?) -2;
518                 Assert (d2 & 1, 0, "#2a");
519
520                 d = new MyType (22);
521                 MyType? v3 = new MyType (30);
522                 Assert (d & v3, new MyType (22), "#3");
523                 dynamic d3 = new MyType? (new MyType (-7));
524                 Assert (d3 & new MyType (6), new MyType (0), "#3a");
525                 Assert<MyType?> (d3 + null, null, "#3b");
526
527                 dynamic a = (bool?) true;
528                 dynamic b = (bool?) null;
529                 Assert (a & b, (bool?)null, "#4a");
530                 Assert (b & a, (bool?)null, "#4b");
531         }
532
533         void AndAssignedTest ()
534         {
535                 dynamic d = true;
536
537                 var v = false;
538                 d &= v;
539                 Assert (d, false, "#1");
540                 d = true;
541                 d &= true;
542                 Assert (d, true, "#1a");
543
544                 d = 42;
545                 var v2 = 62;
546                 d &= v2;
547                 Assert (d, 42, "#2");
548
549                 MyType v3 = new MyType (30);
550                 dynamic d3 = new MyType (-7);
551                 d3 &= new MyType (6);
552                 Assert<MyType> (d3, new MyType (0), "#3");
553         }
554
555         void AndAssignedTestEnum ()
556         {
557                 dynamic d = MyEnum.Value_1;
558                 d &= MyEnum.Value_2;
559                 Assert<MyEnum>(d, 0, "#1");
560
561                 d = MyEnum.Value_2;
562                 d &= d;
563                 Assert (d, MyEnum.Value_2, "#2");
564
565                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
566                 Assert<MyEnumUlong> (d2 & MyEnumUlong.Value_2, 0, "#3");
567         }
568
569         void AndAlsoTest ()
570         {
571                 dynamic d = true;
572
573                 var v = false;
574                 Assert<bool> (d && v, false, "#1");
575                 
576                 Assert (d && true, true, "#1a");
577
578                 d = true;
579                 Assert (d && d, true, "#2");
580
581                 dynamic d3 = new MyType (-7);
582                 Assert<MyType> (d3 && new MyType (6), new MyType (0), "#3");
583         }
584
585         void DivideTest ()
586         {
587                 dynamic d = 5;
588
589                 int v = 2;
590                 Assert (d / v, 2, "#1");
591
592                 d = new MyType (5);
593                 MyType v3 = new MyType (30);
594                 Assert (d / v3, new MyType (0), "#3");
595                 dynamic d3 = new MyType (-7);
596                 Assert<MyType> (d3 + new MyType (6), new MyType (-1), "#3a");
597
598                 d = new MyTypeImplicitOnly (6);
599                 decimal v4 = 4m;
600                 Assert (d / v4, 1.5m, "#4");
601         }
602
603         void DivideNullableTest ()
604         {
605                 dynamic d = 5;
606
607                 double? v2 = null;
608                 Assert<double?> (d / v2, null, "#1");
609                 Assert<double?> (d / null, null, "#1a");
610                 Assert<double?> (null / d, null, "#1b");
611
612                 v2 = -2;
613                 Assert (d / v2, -2.5, "#2");
614                 dynamic d2 = (int?) -2;
615                 Assert (d2 / 1, -2, "#2a");
616
617                 d = new MyType (5);
618                 MyType? v3 = new MyType (30);
619                 Assert (d / v3, new MyType (0), "#3");
620                 dynamic d3 = new MyType? (new MyType (-7));
621                 Assert (d3 / new MyType (6), new MyType (-1), "#3a");
622                 Assert<MyType?> (d3 + null, null, "#3b");
623
624                 d = new MyTypeImplicitOnly (5);
625                 decimal? v4 = 4m;
626                 Assert (d / v4, 1.25m, "#4");
627                 v4 = null;
628                 Assert<decimal?> (d / v4, null, "#4a");
629         }
630
631         void DivideCheckedTest ()
632         {
633                 checked {
634                         // TODO:
635                 }
636         }
637
638         void DivideAssignTest ()
639         {
640                 dynamic d = 5;
641
642                 int v = 2;
643                 d /= v;
644                 Assert (d, 2, "#1");
645
646                 d = 5.0;
647                 double v2 = 0.5;
648                 d /= v2;
649                 Assert (d, 10, "#1a");
650                 d /= v;
651                 Assert (d, 5, "#1b");
652
653                 dynamic d3 = new MyType (-7);
654                 d3 /= new MyType (6);
655                 Assert<MyType> (d3, new MyType (-1), "#3");
656
657                 d = 5m;
658                 decimal v4 = 4m;
659                 d /= v4;
660                 Assert (d, 1.25m, "#4");
661         }
662
663         void DivideAssignCheckedTest ()
664         {
665                 checked {
666                         // TODO:
667                 }
668         }
669
670         void ConvertImplicitTest ()
671         {
672                 dynamic d = 3;
673                 decimal v1 = d;
674                 Assert (3m, v1, "#1");
675
676                 d = new MyTypeImplicitOnly (5);
677                 int v2 = d;
678                 Assert (5, v2, "#2");
679
680                 d = (byte) 4;
681                 int v3 = d;
682                 Assert (4, v3, "#3");
683
684                 int[] v4 = new int[] { d };
685                 Assert (4, v4[0], "#4");
686
687                 d = true;
688                 var v5 = new [] { d, 1 };
689                 Assert (true, v5[0], "#5");
690                 Assert (1, v5[1], "#5a");
691
692                 d = "aa";
693                 bool b = false;
694                 var r = b ? d : "ss";
695                 Assert ("ss", r, "#6");
696                 
697                 var v = new [] { d, 1 };
698                 Assert ("aa", v [0], "#7");
699                 
700                 dynamic [,] a = new dynamic [,] { { 1, 2 }, { 'b', 'x' } };
701                 Assert (2, a [0, 1], "#8");
702                 Assert ('x', a [1, 1], "#8a");
703         }
704
705         int ConvertImplicitReturnTest ()
706         {
707                 dynamic d = (byte) 3;
708                 return d;
709         }
710
711         IEnumerable<string> ConvertImplicitReturnTest_2 ()
712         {
713                 dynamic d = "aaa";
714                 yield return d;
715         }
716
717         void ConvertExplicitTest ()
718         {
719                 dynamic d = 300;
720                 Assert (44, (byte) d, "#1");
721                 Assert<byte?> (44, (byte?) d, "#1a");
722
723                 d = 3m;
724                 Assert (3, d, "#2");
725
726                 d = new MyTypeImplicitOnly (5);
727                 Assert (5, (int) d, "#3");
728
729                 d = new MyTypeExplicit (-2);
730                 Assert (-2, (int) d, "#4");
731
732                 d = null;
733                 Assert (null, (object) d, "#5");
734         }
735
736         void ConvertExplicitCheckedTest ()
737         {
738                 checked {
739                         dynamic d = 300;
740                         AssertChecked (() => (byte) d, 7, "#1");
741
742                         d = ulong.MaxValue;
743                         AssertChecked<uint?> (() => (uint?) d, 2, "#2");
744                 }
745         }
746         
747         void ConvertArray ()
748         {
749                 dynamic idx = (uint) 1;
750                 var arr = new int [5];
751                 arr [idx] = 2;
752                 Assert (2, arr [idx], "#1");
753         }
754
755         void EqualTest ()
756         {
757                 dynamic d = 5;
758
759                 int v = 2;
760                 Assert (d == v, false, "#1");
761                 double v2 = 5;
762                 Assert (d == v2, true, "#1a");
763
764                 d = true;
765                 Assert (d == false, false, "#2");
766                 bool b2 = true;
767                 Assert (d == b2, true, "#2a");
768
769                 d = new MyType (30);
770                 MyType v3 = new MyType (30);
771                 Assert (d == v3, true, "#3");
772                 dynamic d3 = new MyTypeImplicitOnly (-7);
773                 Assert (d3 == 11, false, "#3b");
774                 
775                 d = 2m;
776                 decimal v4 = 4m;
777                 Assert (d == v4, false, "#4");
778                 Assert (d == 2m, true, "#4a");
779                 
780                 d = null;
781                 Assert (d == null, true, "#5");
782         }
783
784         void EqualNullableTest ()
785         {
786                 dynamic d = 5;
787
788                 int? v2 = null;
789                 Assert (d == v2, false, "#1");
790                 Assert (d == null, false, "#1a");
791                 Assert (null == d, false, "#1b");
792
793                 v2 = -2;
794                 Assert (d == v2, false, "#2");
795                 dynamic d2 = (int?) -2;
796                 Assert (d2 == 1, false, "#2a");
797                 d2 = (uint?) 44;
798                 Assert (d2 == 44, true, "#2b");
799
800                 d = new MyType (30);
801                 MyType? v3 = new MyType (30);
802                 Assert (d == v3, true, "#3");
803                 dynamic d3 = new MyType? (new MyType (-7));
804                 Assert (d3 == new MyType (6), false, "#3a");
805                 Assert (d3 == null, false, "#3b");
806                 
807                 d = 4.1m;
808                 decimal? v4 = 4m;
809                 Assert (d == v4, false, "#4");
810                 v4 = null;
811                 Assert (d == v4, false, "#4a");
812
813                 d = (bool?) true;
814                 Assert (d == true, true, "#5");
815                 Assert (d == null, false, "#5a");
816                 Assert (d == false, false, "#5b");
817         }
818
819         void EqualEnumTest ()
820         {
821                 dynamic d = MyEnum.Value_1;
822
823                 Assert (d == null, false, "#1");
824
825                 Assert (d == MyEnum.Value_1, true, "#2");
826                 Assert (d == 0, false, "#2a");
827
828                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
829                 Assert (d2 == MyEnumUlong.Value_2, true, "#3");
830                 Assert (d2 == null, false, "#3a");
831         }
832
833         void EqualStringTest ()
834         {
835                 dynamic d = "text";
836
837                 Assert (d == "te", false, "#1");
838                 Assert (d == "text", true, "#1a");
839                 Assert (d == null, false, "#1b");
840         }
841
842         void EqualDelegateTest ()
843         {
844                 dynamic d = this;
845
846 //              Assert (d == delegate { }, true, "#1");
847
848                 EmptyDelegate b = EqualDelegateTest;
849                 d = b;
850
851                 //Assert (d == EqualDelegateTest, true, "#2");
852         
853 /*
854
855         void EqualTestDelegate_2 ()
856         {
857                 EmptyDelegate ed = delegate () {};
858
859                 Expression<Func<EmptyDelegate, EmptyDelegate, bool>> e2 = (a, b) => a == b;
860                 AssertNodeType (e2, ExpressionType.Equal);
861                 Assert (false, e2.Compile ().Invoke (delegate () {}, null));
862                 Assert (false, e2.Compile ().Invoke (delegate () {}, delegate {}));
863                 Assert (false, e2.Compile ().Invoke (ed, delegate {}));
864                 Assert (true, e2.Compile ().Invoke (ed, ed));
865 */
866         }
867
868         void ExclusiveOrTest ()
869         {
870                 dynamic d = true;
871
872                 var v = false;
873                 Assert (d ^ v, true, "#1");
874                 Assert (d ^ true, false, "#1a");
875
876                 d = 42;
877                 var v2 = 62;
878                 Assert (d ^ v2, 20, "#2");
879                 Assert (d ^ 0, 42, "#2a");
880
881                 d = new MyType (42);
882                 MyType v3 = new MyType (30);
883                 Assert (d ^ v3, new MyType (52), "#3");
884                 dynamic d3 = new MyType (-7);
885                 Assert<MyType> (d3 ^ new MyType (6), new MyType (-1), "#3a");
886
887                 d3 = new MyTypeImplicitOnly (-7);
888                 Assert (d3 ^ 11, -14, "#3b");
889         }
890
891         void ExclusiveOrNullableTest ()
892         {
893                 dynamic d = 5;
894
895                 int? v2 = null;
896                 Assert<int?> (d ^ v2, null, "#1");
897                 Assert<int?> (d ^ null, null, "#1a");
898                 Assert<int?> (null ^ d, null, "#1b");
899
900                 v2 = -2;
901                 Assert (d ^ v2, -5, "#2");
902                 dynamic d2 = (int?) -2;
903                 Assert (d2 ^ 1, -1, "#2a");
904
905                 d = new MyType (5);
906                 MyType? v3 = new MyType (30);
907                 Assert (d ^ v3, new MyType (27), "#3");
908                 dynamic d3 = new MyType? (new MyType (-7));
909                 Assert (d3 ^ new MyType (6), new MyType (-1), "#3a");
910                 Assert<MyType?> (d3 ^ null, null, "#3b");
911         }
912
913         void ExclusiveOrTestEnum ()
914         {
915                 dynamic d = MyEnum.Value_1;
916
917                 Assert<MyEnum?> (d ^ null, null, "#1");
918
919                 Assert<MyEnum> (d ^ d, 0, "#2");
920
921                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
922                 Assert<MyEnumUlong> (d2 ^ MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
923         }
924
925         void ExclusiveOrAssignedTest ()
926         {
927                 dynamic d = true;
928
929                 var v = false;
930                 d ^= v;
931                 Assert (d, true, "#1");
932                 d = true;
933                 d ^= true;
934                 Assert (d, false, "#1a");
935
936                 d = 42;
937                 var v2 = 62;
938                 d ^= v2;
939                 Assert (d, 20, "#2");
940
941                 MyType v3 = new MyType (30);
942                 dynamic d3 = new MyType (-7);
943                 d3 ^= new MyType (6);
944                 Assert (d3, new MyType (-1), "#3");
945         }
946
947         void ExclusiveOrAssignedTestEnum ()
948         {
949                 dynamic d = MyEnum.Value_1;
950                 d ^= MyEnum.Value_2;
951                 Assert<MyEnum>(d, (MyEnum) 3, "#1");
952
953                 d = MyEnum.Value_2;
954                 d ^= d;
955                 Assert<MyEnum> (d, 0, "#2");
956
957                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
958                 Assert (d2 ^ MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
959         }
960
961         void GreaterThanTest ()
962         {
963                 dynamic d = 5;
964
965                 int v = 2;
966                 Assert (d > v, true, "#1");
967                 double v2 = 5;
968                 Assert (d > v2, false, "#1a");
969
970                 d = 4.6;
971                 Assert (d > 4.59, true, "#2");
972                 var b2 = 4.6;
973                 Assert (d > b2, false, "#2a");
974
975                 d = new MyType (30);
976                 MyType v3 = new MyType (30);
977                 Assert (d > v3, false, "#3");
978                 dynamic d3 = new MyType (-7);
979                 Assert (d3 > new MyType (6), false, "#3a");
980
981                 d3 = new MyTypeImplicitOnly (-7);
982                 Assert (d3 > 11, false, "#3b");
983
984                 d = 2m;
985                 decimal v4 = 4m;
986                 Assert (d > v4, false, "#4");
987                 Assert (d > 2m, false, "#4a");
988         }
989
990         void GreaterThanNullableTest ()
991         {
992                 dynamic d = 5;
993
994                 int? v2 = null;
995                 Assert (d > v2, false, "#1");
996                 Assert (d > null, false, "#1a");
997                 Assert (null > d, false, "#1b");
998
999                 v2 = -2;
1000                 Assert (d > v2, true, "#2");
1001                 dynamic d2 = (int?) -2;
1002                 Assert (d2 > 1, false, "#2a");
1003                 d2 = (uint?) 44;
1004                 Assert (d2 > 44, false, "#2b");
1005
1006                 d = new MyType (30);
1007                 MyType? v3 = new MyType (30);
1008                 Assert (d > v3, false, "#3");
1009                 dynamic d3 = new MyType? (new MyType (-7));
1010                 Assert (d3 > new MyType (6), false, "#3a");
1011                 Assert (d3 > null, false, "#3b");
1012
1013                 d = 4.1m;
1014                 decimal? v4 = 4m;
1015                 Assert (d > v4, true, "#4");
1016                 v4 = null;
1017                 Assert (d > v4, false, "#4a");
1018         }
1019
1020         void GreaterThanEnumTest ()
1021         {
1022                 dynamic d = MyEnum.Value_1;
1023
1024                 Assert (d > null, false, "#1");
1025
1026                 Assert (d > MyEnum.Value_1, false, "#2");
1027                 Assert (d > 0, true, "#2a");
1028
1029                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1030                 Assert (d2 > MyEnumUlong.Value_2, false, "#3");
1031                 Assert (d2 > null, false, "#3a");
1032         }
1033
1034         void GreaterThanEqualTest ()
1035         {
1036                 dynamic d = 5;
1037
1038                 int v = 2;
1039                 Assert (d >= v, true, "#1");
1040                 double v2 = 5;
1041                 Assert (d >= v2, true, "#1a");
1042
1043                 d = 4.6;
1044                 Assert (d >= 4.59, true, "#2");
1045                 var b2 = 4.6;
1046                 Assert (d >= b2, true, "#2a");
1047
1048                 d = new MyType (30);
1049                 MyType v3 = new MyType (30);
1050                 Assert (d >= v3, true, "#3");
1051                 dynamic d3 = new MyType (-7);
1052                 Assert (d3 >= new MyType (6), false, "#3a");
1053
1054                 d3 = new MyTypeImplicitOnly (-7);
1055                 Assert (d3 >= 11, false, "#3b");
1056
1057                 d = 2m;
1058                 decimal v4 = 4m;
1059                 Assert (d >= v4, false, "#4");
1060                 Assert (d >= 2m, true, "#4a");
1061         }
1062
1063         void GreaterThanEqualNullableTest ()
1064         {
1065                 dynamic d = 5;
1066
1067                 int? v2 = null;
1068                 Assert (d >= v2, false, "#1");
1069                 Assert (d >= null, false, "#1a");
1070                 Assert (null >= d, false, "#1b");
1071
1072                 v2 = -2;
1073                 Assert (d >= v2, true, "#2");
1074                 dynamic d2 = (int?) -2;
1075                 Assert (d2 >= 1, false, "#2a");
1076                 d2 = (uint?) 44;
1077                 Assert (d2 >= 44, true, "#2b");
1078
1079                 d = new MyType (30);
1080                 MyType? v3 = new MyType (30);
1081                 Assert (d >= v3, true, "#3");
1082                 dynamic d3 = new MyType? (new MyType (-7));
1083                 Assert (d3 >= new MyType (6), false, "#3a");
1084                 Assert (d3 >= null, false, "#3b");
1085
1086                 d = 4.1m;
1087                 decimal? v4 = 4m;
1088                 Assert (d >= v4, true, "#4");
1089                 v4 = null;
1090                 Assert (d >= v4, false, "#4a");
1091         }
1092
1093         void GreaterThanEqualEnumTest ()
1094         {
1095                 dynamic d = MyEnum.Value_1;
1096
1097                 Assert (d >= null, false, "#1");
1098
1099                 Assert (d >= MyEnum.Value_1, true, "#2");
1100                 Assert (d >= 0, true, "#2a");
1101
1102                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1103                 Assert (d2 >= MyEnumUlong.Value_2, true, "#3");
1104                 Assert (d2 >= null, false, "#3a");
1105         }
1106
1107         void LeftShiftTest ()
1108         {
1109                 dynamic d = (ulong) 0x7F000;
1110
1111                 int v = 2;
1112                 Assert<ulong> (d << v, 0x1FC000, "#1");
1113                 Assert<ulong> (d << 1, 0xFE000, "#1a");
1114                 short s = 2;
1115                 Assert<ulong> (d << s, 0x1FC000, "#1b");
1116
1117                 d = 0x7F000;
1118                 MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
1119                 Assert (d << v3, 0x3F8000, "#3");
1120                 dynamic d3 = new MyType (-7);
1121                 Assert (d3 << new MyTypeImplicitOnly (6), -448, "#3a");
1122                 Assert (d3 << 11, -14336, "#3b");
1123         }
1124
1125         void LeftShiftNullableTest ()
1126         {
1127                 dynamic d = 5;
1128
1129                 int? v2 = null;
1130                 Assert<int?> (d << v2, null, "#1");
1131                 d = 5;
1132                 Assert<int?> (d << null, null, "#1a");
1133                 d = 5;
1134                 Assert<int?> (null << d, null, "#1b");
1135
1136                 v2 = -2;
1137                 Assert (d << v2, 0x40000000, "#2");
1138                 dynamic d2 = (int?) -2;
1139                 Assert (d2 << 1, -4, "#2a");
1140
1141                 dynamic d3 = (int?) null;
1142                 Assert (d3 << (null << null), (int?)null, "#3");
1143         }
1144
1145         void LeftShiftAssignTest ()
1146         {
1147                 dynamic d = 0x7F000;
1148
1149                 int v = 2;
1150                 d <<= v;
1151                 Assert (d, 0x1FC000, "#1");
1152                 d <<= 1;
1153                 Assert (d, 0x3F8000, "#1a");
1154                 sbyte s = 2;
1155                 d <<= s;
1156                 Assert (d, 0xFE0000, "#1b");
1157         }
1158
1159         void LeftShiftAssignNullableTest ()
1160         {
1161                 dynamic d = 5;
1162
1163                 var v2 = -2;
1164                 d <<= v2;
1165                 Assert (d, 0x40000000, "#2");
1166                 dynamic d2 = (int?) -2;
1167                 d2 <<= 1;
1168                 Assert (d2, -4, "#2a");
1169         }
1170
1171         void LessThanTest ()
1172         {
1173                 dynamic d = 5;
1174
1175                 int v = 2;
1176                 Assert (d < v, false, "#1");
1177                 double v2 = 5;
1178                 Assert (d < v2, false, "#1a");
1179
1180                 d = 4.6;
1181                 Assert (d < 4.59, false, "#2");
1182                 var b2 = 4.6;
1183                 Assert (d < b2, false, "#2a");
1184
1185                 d = new MyType (30);
1186                 MyType v3 = new MyType (30);
1187                 Assert (d < v3, false, "#3");
1188                 dynamic d3 = new MyType (-7);
1189                 Assert (d3 < new MyType (6), true, "#3a");
1190
1191                 d3 = new MyTypeImplicitOnly (-7);
1192                 Assert (d3 < 11, true, "#3b");
1193
1194                 d = 2m;
1195                 decimal v4 = 4m;
1196                 Assert (d < v4, true, "#4");
1197                 Assert (d < 2m, false, "#4a");
1198         }
1199
1200         void LessThanNullableTest ()
1201         {
1202                 dynamic d = 5;
1203
1204                 int? v2 = null;
1205                 Assert (d < v2, false, "#1");
1206                 Assert (d < null, false, "#1a");
1207                 Assert (null < d, false, "#1b");
1208
1209                 v2 = -2;
1210                 Assert (d < v2, false, "#2");
1211                 dynamic d2 = (int?) -2;
1212                 Assert (d2 < 1, true, "#2a");
1213                 d2 = (uint?) 44;
1214                 Assert (d2 < 44, false, "#2b");
1215
1216                 d = new MyType (30);
1217                 MyType? v3 = new MyType (30);
1218                 Assert (d < v3, false, "#3");
1219                 dynamic d3 = new MyType? (new MyType (-7));
1220                 Assert (d3 < new MyType (6), true, "#3a");
1221
1222                 d3 = new MyTypeImplicitOnly (-7);
1223                 Assert (d3 < null, false, "#3b");
1224
1225                 d = 4.1m;
1226                 decimal? v4 = 4m;
1227                 Assert (d < v4, false, "#4");
1228                 v4 = null;
1229                 Assert (d < v4, false, "#4a");
1230         }
1231
1232         void LessThanEnumTest ()
1233         {
1234                 dynamic d = MyEnum.Value_1;
1235
1236                 Assert (d < null, false, "#1");
1237
1238                 Assert (d < MyEnum.Value_1, false, "#2");
1239                 Assert (d < 0, false, "#2a");
1240
1241                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1242                 Assert (d2 < MyEnumUlong.Value_2, false, "#3");
1243                 Assert (d2 < null, false, "#3a");
1244         }
1245
1246         void LessThanOrEqualTest ()
1247         {
1248                 dynamic d = 5;
1249
1250                 int v = 2;
1251                 Assert (d <= v, false, "#1");
1252                 double v2 = 5;
1253                 Assert (d <= v2, true, "#1a");
1254
1255                 d = 4.6;
1256                 Assert (d <= 4.59, false, "#2");
1257                 var b2 = 4.6;
1258                 Assert (d <= b2, true, "#2a");
1259
1260                 d = new MyType (30);
1261                 MyType v3 = new MyType (30);
1262                 Assert (d <= v3, true, "#3");
1263                 dynamic d3 = new MyType (-7);
1264                 Assert (d3 <= new MyType (6), true, "#3a");
1265
1266                 d3 = new MyTypeImplicitOnly (-7);
1267                 Assert (d3 <= 11, true, "#3b");
1268
1269                 d = 2m;
1270                 decimal v4 = 4m;
1271                 Assert (d <= v4, true, "#4");
1272                 Assert (d <= 2m, true, "#4a");
1273         }
1274
1275         void LessThanOrEqualNullableTest ()
1276         {
1277                 dynamic d = 5;
1278
1279                 int? v2 = null;
1280                 Assert (d <= v2, false, "#1");
1281                 Assert (d <= null, false, "#1a");
1282                 Assert (null <= d, false, "#1b");
1283
1284                 v2 = -2;
1285                 Assert (d <= v2, false, "#2");
1286                 dynamic d2 = (int?) -2;
1287                 Assert (d2 <= 1, true, "#2a");
1288                 d2 = (uint?) 44;
1289                 Assert (d2 <= 44, true, "#2b");
1290
1291                 d = new MyType (30);
1292                 MyType? v3 = new MyType (30);
1293                 Assert (d <= v3, true, "#3");
1294                 dynamic d3 = new MyType? (new MyType (-7));
1295                 Assert (d3 <= new MyType (6), true, "#3a");
1296                 Assert (d3 <= null, false, "#3b");
1297
1298                 d = 4.1m;
1299                 decimal? v4 = 4m;
1300                 Assert (d <= v4, false, "#4");
1301                 v4 = null;
1302                 Assert (d <= v4, false, "#4a");
1303         }
1304
1305         void LessThanOrEqualEnumTest ()
1306         {
1307                 dynamic d = MyEnum.Value_1;
1308
1309                 Assert (d <= null, false, "#1");
1310
1311                 Assert (d <= MyEnum.Value_1, true, "#2");
1312                 Assert (d <= 0, false, "#2a");
1313
1314                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1315                 Assert (d2 <= MyEnumUlong.Value_2, true, "#3");
1316                 Assert (d2 <= null, false, "#3a");
1317         }
1318
1319         void ModuloTest ()
1320         {
1321                 dynamic d = 5;
1322
1323                 int v = 2;
1324                 Assert (d % v, 1, "#1");
1325
1326                 d = new MyType (5);
1327                 MyType v3 = new MyType (30);
1328                 Assert (d % v3, new MyType (5), "#3");
1329                 dynamic d3 = new MyType (-7);
1330                 Assert<MyType> (d3 % new MyType (6), new MyType (-1), "#3a");
1331
1332                 d = new MyTypeImplicitOnly (5);
1333                 decimal v4 = 4m;
1334                 Assert (d % v4, 1m, "#4");
1335         }
1336
1337         void ModuloNullableTest ()
1338         {
1339                 dynamic d = 5;
1340
1341                 double? v2 = null;
1342                 Assert<double?> (d % v2, null, "#1");
1343                 Assert<double?> (d % null, null, "#1a");
1344                 Assert<double?> (null % d, null, "#1b");
1345
1346                 v2 = -2;
1347                 Assert (d % v2, 1, "#2");
1348                 dynamic d2 = (int?) -2;
1349                 Assert (d2 % 1, 0, "#2a");
1350
1351                 d = new MyType (-2);
1352                 MyType? v3 = new MyType (30);
1353                 Assert (d % v3, new MyType (-2), "#3");
1354                 dynamic d3 = new MyType? (new MyType (-7));
1355                 Assert (d3 % new MyType (6), new MyType (-1), "#3a");
1356                 Assert<MyType?> (d3 + null, null, "#3b");
1357
1358                 d = new MyTypeImplicitOnly (5);
1359                 decimal? v4 = 4m;
1360                 Assert (d % v4, 1m, "#4");
1361                 v4 = null;
1362                 Assert<decimal?> (d % v4, null, "#4a");
1363         }
1364
1365         void ModuloAssignTest ()
1366         {
1367                 dynamic d = 5;
1368
1369                 int v = 2;
1370                 d %= v;
1371                 Assert (d, 1, "#1");
1372
1373                 d = 5.0;
1374                 double v2 = 0.5;
1375                 d %= v2;
1376                 Assert (d, 0, "#1a");
1377                 d %= v;
1378                 Assert (d, 0, "#1b");
1379
1380                 dynamic d3 = new MyType (-7);
1381                 d3 %= new MyType (6);
1382                 Assert<MyType> (d3, new MyType (-1), "#3");
1383
1384                 d = 5m;
1385                 decimal v4 = 4m;
1386                 d %= v4;
1387                 Assert (d, 1m, "#4");
1388         }
1389
1390         void MultiplyTest ()
1391         {
1392                 dynamic d = 5;
1393
1394                 int v = 2;
1395                 Assert (d * v, 10, "#1");
1396                 double v2 = 0.5;
1397                 Assert (d * v2, 2.5, "#1a");
1398
1399                 d = new MyType (5);
1400                 MyType v3 = new MyType (30);
1401                 Assert (d * v3, new MyType (150), "#3");
1402                 dynamic d3 = new MyType (-7);
1403                 Assert<MyType> (d3 * new MyType (6), new MyType (-42), "#3a");
1404
1405                 decimal v4 = 4m;
1406                 d = 7.9m;
1407                 Assert (d * v4, 31.6m, "#4");
1408         }
1409
1410         void MultiplyNullableTest ()
1411         {
1412                 dynamic d = 5;
1413
1414                 int? v2 = null;
1415                 Assert<int?> (d * v2, null, "#1");
1416                 Assert<int?> (d * null, null, "#1a");
1417                 Assert<int?> (null * d, null, "#1b");
1418
1419                 v2 = -2;
1420                 Assert (d * v2, -10, "#2");
1421                 dynamic d2 = (int?) -2;
1422                 Assert (d2 * 1, -2, "#2a");
1423
1424                 d = new MyType (5);
1425                 MyType? v3 = new MyType (30);
1426                 Assert (d * v3, new MyType (150), "#3");
1427                 dynamic d3 = new MyType? (new MyType (-7));
1428                 Assert (d3 * new MyType (6), new MyType (-42), "#3a");
1429                 Assert<MyType?> (d3 * null, null, "#3b");
1430
1431                 d = new MyTypeImplicitOnly (5);
1432                 decimal? v4 = 4m;
1433                 Assert (d * v4, 20m, "#4");
1434                 v4 = null;
1435                 Assert<decimal?> (d * v4, null, "#4a");
1436         }
1437
1438         void MultiplyCheckedTest ()
1439         {
1440                 checked {
1441                         dynamic d = 5;
1442
1443                         int v = int.MaxValue;
1444                         AssertChecked (() => d * v, 7, "#1");
1445
1446                         int? v2 = v;
1447                         AssertChecked (() => d * v2, null, "#2");
1448
1449                         d = new MyType (4);
1450                         MyType v3 = new MyType (int.MaxValue);
1451                         Assert (d * v3, new MyType (-4), "#3");
1452                 }
1453         }
1454
1455         void MultiplyAssignTest ()
1456         {
1457                 dynamic d = 5;
1458
1459                 int v = 2;
1460                 d *= v;
1461                 Assert (d, 10, "#1");
1462
1463                 d = 5.0;
1464                 double v2 = 0.5;
1465                 d *= v2;
1466                 Assert (d, 2.5, "#1a");
1467                 d *= v;
1468                 Assert (d, 5, "#1b");
1469
1470                 dynamic d3 = new MyType (-7);
1471                 d3 *= new MyType (6);
1472                 Assert<MyType> (d3, new MyType (-42), "#3");
1473
1474                 d = 5m;
1475                 decimal v4 = 4m;
1476                 d *= v4;
1477                 Assert (d, 20m, "#4");
1478                 
1479                 int i = 3;
1480                 d = 5;
1481                 i *= d;
1482                 Assert (i, 15, "#5");
1483         }
1484
1485         void MultiplyAssignCheckedTest ()
1486         {
1487                 checked {
1488                         dynamic d = 5;
1489
1490                         int v = int.MaxValue;
1491                         AssertChecked (() => { d *= v; Assert (d, 0, "#1-"); }, "#1");
1492
1493                         d = new MyType (44);
1494                         MyType v3 = new MyType (int.MaxValue);
1495                         d *= v3;
1496                         Assert (d, new MyType (-44), "#3-");
1497                 }
1498         }
1499
1500         void Negate ()
1501         {
1502                 dynamic d = -8;
1503                 Assert (8, -d, "#1");
1504                 Assert (-8, -(-d), "#1a");
1505
1506                 d = new MyType (-14);
1507                 Assert (new MyType (14), -d, "#2");
1508
1509                 d = new MyTypeImplicitOnly (4);
1510                 Assert (-4, -d, "#3");
1511
1512                 d = (uint) 7;
1513                 Assert (-7, -d, "#4");
1514
1515                 d = double.NegativeInfinity;
1516                 Assert (double.PositiveInfinity, -d, "#5");
1517         }
1518
1519         void NegateNullable ()
1520         {
1521                 dynamic d = (int?) -8;
1522                 Assert (8, -d, "#1");
1523                 Assert (-8, -(-d), "#1a");
1524
1525                 MyType? n1 = new MyType (4);
1526                 d = n1;
1527                 Assert (new MyType (-4), -d, "#2");
1528
1529                 MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
1530                 d = n2;
1531                 Assert (-4, -d, "#3");
1532
1533                 d = (sbyte?) 7;
1534                 Assert (-7, -d, "#4");
1535         }
1536
1537         void NegateChecked ()
1538         {
1539                 checked {
1540                         dynamic d = int.MinValue;
1541                         AssertChecked (() => -d, 0, "#1");
1542                 }
1543         }
1544
1545         void Not ()
1546         {
1547                 dynamic d = true;
1548                 Assert (false, !d, "#1");
1549
1550                 var de = new MyType (-1);
1551                 Assert (false, !d, "#2");
1552         }
1553
1554         void NotEqualTest ()
1555         {
1556                 dynamic d = 5;
1557
1558                 int v = 2;
1559                 Assert (d != v, true, "#1");
1560                 double v2 = 5;
1561                 Assert (d != v2, false, "#1a");
1562
1563                 d = true;
1564                 Assert (d != false, true, "#2");
1565                 bool b2 = true;
1566                 Assert (d != b2, false, "#2a");
1567
1568                 d = new MyType (30);
1569                 MyType v3 = new MyType (30);
1570                 Assert (d != v3, false, "#3");
1571                 dynamic d3 = new MyType (-7);
1572                 Assert (d3 != new MyType (6), true, "#3a");
1573
1574                 d = 2m;
1575                 decimal v4 = 4m;
1576                 Assert (d != v4, true, "#4");
1577                 Assert (d != 2m, false, "#4a");
1578
1579                 d = null;
1580                 Assert (d != null, false, "#5");
1581         }
1582
1583         void NotEqualNullableTest ()
1584         {
1585                 dynamic d = 5;
1586
1587                 int? v2 = null;
1588                 Assert (d != v2, true, "#1");
1589                 Assert (d != null, true, "#1a");
1590                 Assert (null != d, true, "#1b");
1591
1592                 v2 = -2;
1593                 Assert (d != v2, true, "#2");
1594                 dynamic d2 = (int?) -2;
1595                 Assert (d2 != 1, true, "#2a");
1596                 d2 = (uint?) 44;
1597                 Assert (d2 != 44, false, "#2b");
1598
1599                 d = new MyType (30);
1600                 MyType? v3 = new MyType (30);
1601                 Assert (d != v3, false, "#3");
1602                 dynamic d3 = new MyType? (new MyType (-7));
1603                 Assert (d3 != new MyType (6), true, "#3a");
1604                 Assert (d3 != null, true, "#3b");
1605
1606                 d = 4.1m;
1607                 decimal? v4 = 4m;
1608                 Assert (d != v4, true, "#4");
1609                 v4 = null;
1610                 Assert (d != v4, true, "#4a");
1611
1612                 d = (bool?) true;
1613                 Assert (d != true, false, "#5");
1614                 Assert (d != null, true, "#5a");
1615                 Assert (d != false, true, "#5b");
1616
1617                 d = null;
1618                 long? l = null;
1619                 Assert (d != l, false, "#6a");
1620                 Assert (l != d, false, "#6b");
1621         }
1622
1623         void NotEqualEnumTest ()
1624         {
1625                 dynamic d = MyEnum.Value_1;
1626
1627                 Assert (d != null, true, "#1");
1628
1629                 Assert (d != MyEnum.Value_1, false, "#2");
1630                 Assert (d != 0, true, "#2a");
1631
1632                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1633                 Assert (d2 != MyEnumUlong.Value_2, false, "#3");
1634                 Assert (d2 != null, true, "#3a");
1635         }
1636
1637         void NotEqualStringTest ()
1638         {
1639                 dynamic d = "text";
1640
1641                 Assert (d != "te", true, "#1");
1642                 Assert (d != "text", false, "#1a");
1643                 Assert (d != null, true, "#1b");
1644         }
1645
1646         void OnesComplement ()
1647         {
1648                 dynamic d = 7;
1649                 Assert (-8, ~d, "#1");
1650
1651                 d = new MyType (-1);
1652                 Assert (0, ~d, "#2");
1653
1654                 d = (ulong) 7;
1655                 Assert (18446744073709551608, ~d, "#3");
1656
1657                 d = MyEnum.Value_1;
1658                 Assert ((MyEnum) 254, ~d, "#4");
1659         }
1660
1661         void OnesComplementNullable ()
1662         {
1663                 dynamic d = (int?) 7;
1664                 Assert (-8, ~d, "#1");
1665
1666                 d = (MyEnum?) MyEnum.Value_1;
1667                 Assert ((MyEnum) 254, ~d, "#4");
1668         }
1669
1670         void OrTest ()
1671         {
1672                 dynamic d = true;
1673
1674                 var v = false;
1675                 Assert (d | v, true, "#1");
1676                 Assert (d | false, true, "#1a");
1677
1678                 d = 42;
1679                 var v2 = 62;
1680                 Assert (d | v2, 62, "#2");
1681                 Assert (d | 0, 42, "#2a");
1682
1683                 d = new MyType (42);
1684                 MyType v3 = new MyType (30);
1685                 Assert (d | v3, new MyType (62), "#3");
1686                 dynamic d3 = new MyType (-7);
1687                 Assert<MyType> (d3 | new MyType (6), new MyType (-1), "#3a");
1688
1689                 d3 = new MyTypeImplicitOnly (-7);
1690                 Assert (d3 | 11, -5, "#3b");
1691         }
1692
1693         void OrTestEnum ()
1694         {
1695                 dynamic d = MyEnum.Value_1;
1696
1697                 Assert<MyEnum?> (d | null, null, "#1");
1698
1699                 Assert (d | d, MyEnum.Value_1, "#2");
1700
1701                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1702                 Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
1703         }
1704
1705         void OrTestNullable ()
1706         {
1707                 dynamic d = 5;
1708
1709                 int? v2 = null;
1710                 Assert<int?> (d | v2, null, "#1");
1711                 Assert<int?> (d | null, null, "#1a");
1712                 Assert<int?> (null | d, null, "#1b");
1713
1714                 v2 = -2;
1715                 Assert (d | v2, -1, "#2");
1716                 dynamic d2 = (int?) -2;
1717                 Assert (d2 | 1, -1, "#2a");
1718
1719                 d = new MyType (-2);
1720                 MyType? v3 = new MyType (30);
1721                 Assert (d | v3, new MyType (-2), "#3");
1722                 dynamic d3 = new MyType? (new MyType (-7));
1723                 Assert (d3 | new MyType (6), new MyType (-1), "#3a");
1724         }
1725
1726         void OrAssignedTest ()
1727         {
1728                 dynamic d = true;
1729
1730                 var v = false;
1731                 d |= v;
1732                 Assert (d, true, "#1");
1733                 d = true;
1734                 d |= true;
1735                 Assert (d, true, "#1a");
1736
1737                 d = 42;
1738                 var v2 = 62;
1739                 d |= v2;
1740                 Assert (d, 62, "#2");
1741
1742                 MyType v3 = new MyType (30);
1743                 dynamic d3 = new MyType (-7);
1744                 d3 |= new MyType (6);
1745                 Assert<MyType> (d3, new MyType (-1), "#3");
1746         }
1747
1748         void OrAssignedTestEnum ()
1749         {
1750                 dynamic d = MyEnum.Value_1;
1751                 d |= MyEnum.Value_2;
1752                 Assert<MyEnum> (d, (MyEnum) 3, "#1");
1753
1754                 d = MyEnum.Value_2;
1755                 d |= d;
1756                 Assert (d, MyEnum.Value_2, "#2");
1757
1758                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1759                 Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
1760         }
1761
1762         void OrElseTest ()
1763         {
1764                 dynamic d = true;
1765
1766                 var v = false;
1767                 Assert<bool> (d || v, true, "#1");
1768
1769                 Assert (d || true, true, "#1a");
1770
1771                 d = true;
1772                 Assert (d || d, true, "#2");
1773
1774                 dynamic d3 = new MyType (-7);
1775                 Assert<MyType> (d3 || new MyType (6), new MyType (-7), "#3");
1776         }
1777
1778         void RightShiftTest ()
1779         {
1780                 dynamic d = (ulong) 0x7F000;
1781
1782                 int v = 2;
1783                 Assert<ulong> (d >> v, 0x1FC00, "#1");
1784                 Assert<ulong> (d >> 1, 0x3F800, "#1a");
1785                 short s = 2;
1786                 Assert<ulong> (d >> s, 0x1FC00, "#1b");
1787
1788                 d = 0x7F000;
1789                 MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
1790                 Assert (d >> v3, 0xFE00, "#3");
1791                 dynamic d3 = new MyType (-7);
1792                 Assert (d3 >> new MyTypeImplicitOnly (11), -1, "#3a");
1793         }
1794
1795         void RightShiftNullableTest ()
1796         {
1797                 dynamic d = 5;
1798
1799                 int? v2 = null;
1800                 Assert<int?> (d >> v2, null, "#1");
1801                 d = 5;
1802                 Assert<int?> (d >> null, null, "#1a");
1803                 d = 5;
1804                 Assert<int?> (null >> d, null, "#1b");
1805
1806                 v2 = -2;
1807                 Assert (d >> v2, 0, "#2");
1808                 dynamic d2 = (int?) -200;
1809                 Assert (d2 >> 1, -100, "#2a");
1810
1811                 dynamic d3 = (int?) null;
1812                 Assert (d3 >> (null >> null), (int?) null, "#3");
1813         }
1814
1815         void RightShiftAssignTest ()
1816         {
1817                 dynamic d = 0x7F000;
1818
1819                 int v = 2;
1820                 d >>= v;
1821                 Assert (d, 0x1FC00, "#1");
1822                 d >>= 1;
1823                 Assert (d, 0xFE00, "#1a");
1824                 sbyte s = 2;
1825                 d >>= s;
1826                 Assert (d, 0x3F80, "#1b");
1827         }
1828
1829         void RightShiftAssignNullableTest ()
1830         {
1831                 dynamic d = 0x2A0;
1832
1833                 var v2 = -2;
1834                 d >>= v2;
1835                 Assert (d, 0, "#2");
1836                 dynamic d2 = (int?) -2;
1837                 d2 >>= 1;
1838                 Assert (d2, -1, "#2a");
1839         }
1840
1841         void SubtractTest ()
1842         {
1843                 dynamic d = 5;
1844
1845                 int v = 2;
1846                 Assert (d - v, 3, "#1");
1847                 double v2 = 0.5;
1848                 Assert (d - v2, 4.5, "#1a");
1849
1850                 d = new MyType (5);
1851                 MyType v3 = new MyType (30);
1852                 Assert (d - v3, new MyType (-25), "#3");
1853                 dynamic d3 = new MyType (-7);
1854                 Assert (d3 - new MyType (6), new MyType (-13), "#3a");
1855
1856                 d = new MyTypeImplicitOnly (5);
1857                 decimal v4 = 4m;
1858                 Assert (d - v4, 1m, "#4");
1859         }
1860
1861         void SubtractNullableTest ()
1862         {
1863                 dynamic d = 5;
1864
1865                 int? v2 = null;
1866                 Assert<int?> (d - v2, null, "#1");
1867                 Assert<int?> (d - null, null, "#1a");
1868                 Assert<int?> (null - d, null, "#1b");
1869
1870                 v2 = -2;
1871                 Assert (d - v2, 7, "#2");
1872                 dynamic d2 = (int?) -2;
1873                 Assert (d2 - 1, -3, "#2a");
1874
1875                 d = new MyType (5);
1876                 MyType? v3 = new MyType (30);
1877                 Assert (d - v3, new MyType (-25), "#3");
1878                 dynamic d3 = new MyType? (new MyType (-7));
1879                 Assert (d3 - new MyType (6), new MyType (-13), "#3a");
1880                 Assert<MyType?> (d3 - null, null, "#3b");
1881
1882                 d = new MyTypeImplicitOnly (5);
1883                 decimal? v4 = 4m;
1884                 Assert (d - v4, 1m, "#4");
1885                 v4 = null;
1886                 Assert<decimal?> (d - v4, null, "#4a");
1887         }
1888
1889         void SubtractEnumTest ()
1890         {
1891                 dynamic d = MyEnum.Value_1;
1892
1893                 Assert<MyEnum> (d - 1, 0, "#1");
1894
1895                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1896                 Assert (d2 - (byte) 1, MyEnumUlong.Value_1, "#2");
1897                 Assert<MyEnumUlong?> (d2 - null, null, "#2a");
1898                 
1899                 // CSC: Invalid System.InvalidOperationException
1900                 Assert<MyEnum?> (d - null, null, "#3");
1901         }
1902
1903         void SubtractCheckedTest ()
1904         {
1905                 checked {
1906                         dynamic d = 5;
1907
1908                         int v = int.MinValue;
1909                         AssertChecked (() => d - v, 7, "#1");
1910
1911                         int? v2 = v;
1912                         AssertChecked (() => d - v2, null, "#2");
1913
1914                         d = new MyType (5);
1915                         MyType v3 = new MyType (int.MinValue);
1916                         Assert (d - v3, new MyType (-2147483643), "#3");
1917                 }
1918         }
1919
1920         void SubtractAssignTest ()
1921         {
1922                 dynamic d = 5;
1923
1924                 int v = 2;
1925                 d -= v;
1926                 Assert (d, 3, "#1");
1927
1928                 d = 5.0;
1929                 double v2 = 0.5;
1930                 d -= v2;
1931                 Assert (d, 4.5, "#1a");
1932                 d -= v;
1933                 Assert (d, 2.5, "#1b");
1934
1935                 dynamic d3 = new MyType (-7);
1936                 d3 -= new MyType (6);
1937                 Assert<MyType> (d3, new MyType (-13), "#3");
1938
1939                 d = 5m;
1940                 decimal v4 = 4m;
1941                 d -= v4;
1942                 Assert (d, 1m, "#4");
1943         }
1944
1945         void SubtractAssignEnumTest ()
1946         {
1947                 dynamic d = MyEnum.Value_1;
1948
1949                 d -= 1;
1950                 Assert<MyEnum> (d, 0, "#2");
1951
1952                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1953                 d2 -= (byte) 1;
1954                 Assert (d2, MyEnumUlong.Value_1, "#3");
1955         }
1956
1957         void SubtractAssignCheckedTest ()
1958         {
1959                 checked {
1960                         dynamic d = 5;
1961
1962                         int v = int.MinValue;
1963                         AssertChecked (() => { d -= v; Assert (d, 0, "#1a"); }, "#1");
1964
1965                         d = new MyType (5);
1966                         MyType v3 = new MyType (int.MinValue);
1967                         d -= v3;
1968                         Assert (d, new MyType (-2147483643), "#3a");
1969                 }
1970         }
1971
1972         void SubtractAssignEvent ()
1973         {
1974                 Action print = () => { Console.WriteLine ("foo"); };
1975                 dynamic d = print;
1976                 
1977                 // FIXME: Will have to special case events
1978                 //ev_assign -= d;
1979                 //ev_assign ();
1980         }
1981
1982         void UnaryDecrement ()
1983         {
1984                 dynamic d = 3;
1985                 Assert (3, d--, "#1");
1986                 Assert (2, d, "#1a");
1987
1988                 d = 3;
1989                 Assert (2, --d, "#2");
1990                 Assert (2, d, "#2a");
1991
1992                 d = new MyType (-3);
1993                 Assert (new MyType (-3), d--, "#3");
1994                 Assert (new MyType (-1), d, "#3a");
1995         }
1996
1997         void UnaryDecrementCheckedTest ()
1998         {
1999                 checked {
2000                         dynamic d = int.MinValue;
2001
2002                         AssertChecked (() => { d--; Assert (d, -1073741824, "#1a"); }, "#1");
2003
2004                         d = new MyType (int.MinValue);
2005                         d--;
2006                         Assert (d, new MyType (-1073741824), "#2");
2007                 }
2008         }
2009
2010         void UnaryIncrement ()
2011         {
2012                 dynamic d = 3;
2013                 Assert (3, d++, "#1");
2014                 Assert (4, d, "#1a");
2015
2016                 d = 3;
2017                 Assert (4, ++d, "#2");
2018                 Assert (4, d, "#2a");
2019
2020                 d = new MyType (-3);
2021                 Assert (new MyType (-3), d++, "#3");
2022                 Assert (new MyType (-6), d, "#3a");
2023         }
2024
2025         void UnaryIncrementCheckedTest ()
2026         {
2027                 checked {
2028                         dynamic d = int.MaxValue;
2029
2030                         AssertChecked (() => { d++; Assert (d, 0, "#1a"); }, "#1");
2031
2032                         d = new MyType (int.MaxValue);
2033                         d++;
2034                         Assert (d, new MyType (-2), "#2");
2035                 }
2036         }
2037
2038         //void UnaryIsFalse ()
2039         //{
2040         //    dynamic d = this;
2041         //    object r = d == null;
2042         //    Assert (false, (bool) r, "#1");
2043         //    Assert<object> (true, d != null, "#1a");
2044         //}
2045
2046         void UnaryIsTrue ()
2047         {
2048                 dynamic d = true;
2049                 Assert (3, d ? 3 : 5, "#1");
2050
2051                 d = 4;
2052                 Assert (false, d < 1, "#2");
2053
2054                 d = new InverseLogicalOperator (true);
2055                 Assert (1, d ? 1 : -1, "#3");
2056         }
2057
2058         void UnaryPlus ()
2059         {
2060                 dynamic d = -8;
2061                 Assert (-8, +d, "#1");
2062                 Assert (-8, +(+d), "#1a");
2063
2064                 d = new MyType (14);
2065                 Assert (new MyType (334455), +d, "#2");
2066
2067                 d = new MyTypeImplicitOnly (4);
2068                 Assert (4, +d, "#3");
2069
2070                 d = (uint) 7;
2071                 Assert<uint> (7, +d, "#4");
2072         }
2073
2074         void UnaryPlusNullable ()
2075         {
2076                 dynamic d = (int?) -8;
2077                 Assert (-8, +d, "#1");
2078                 Assert (-8, +(+d), "#1a");
2079
2080                 MyType? n1 = new MyType (4);
2081                 d = n1;
2082                 Assert (new MyType (334455), +d, "#2");
2083
2084                 MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
2085                 d = n2;
2086                 Assert (4, +d, "#3");
2087
2088                 d = (sbyte?) 7;
2089                 Assert (7, +d, "#4");
2090         }
2091
2092 #pragma warning restore 169
2093
2094         static bool RunTest (MethodInfo test)
2095         {
2096                 Console.Write ("Running test {0, -25}", test.Name);
2097                 try {
2098                         test.Invoke (new Tester (), null);
2099                         Console.WriteLine ("OK");
2100                         return true;
2101                 } catch (Exception e) {
2102                         Console.WriteLine ("FAILED");
2103                         Console.WriteLine (e.ToString ());
2104                         return false;
2105                 }
2106         }
2107
2108         public static int Main ()
2109         {
2110                 var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
2111                                         where test.GetParameters ().Length == 0
2112                                         orderby test.Name
2113                                         select RunTest (test);
2114
2115                 int failures = tests.Count (a => !a);
2116                 Console.WriteLine (failures + " tests failed");
2117                 return failures;
2118         }
2119 }
2120