Merge pull request #778 from cmorris98/master
[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
528         void AndAssignedTest ()
529         {
530                 dynamic d = true;
531
532                 var v = false;
533                 d &= v;
534                 Assert (d, false, "#1");
535                 d = true;
536                 d &= true;
537                 Assert (d, true, "#1a");
538
539                 d = 42;
540                 var v2 = 62;
541                 d &= v2;
542                 Assert (d, 42, "#2");
543
544                 MyType v3 = new MyType (30);
545                 dynamic d3 = new MyType (-7);
546                 d3 &= new MyType (6);
547                 Assert<MyType> (d3, new MyType (0), "#3");
548         }
549
550         void AndAssignedTestEnum ()
551         {
552                 dynamic d = MyEnum.Value_1;
553                 d &= MyEnum.Value_2;
554                 Assert<MyEnum>(d, 0, "#1");
555
556                 d = MyEnum.Value_2;
557                 d &= d;
558                 Assert (d, MyEnum.Value_2, "#2");
559
560                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
561                 Assert<MyEnumUlong> (d2 & MyEnumUlong.Value_2, 0, "#3");
562         }
563
564         void AndAlsoTest ()
565         {
566                 dynamic d = true;
567
568                 var v = false;
569                 Assert<bool> (d && v, false, "#1");
570                 
571                 Assert (d && true, true, "#1a");
572
573                 d = true;
574                 Assert (d && d, true, "#2");
575
576                 dynamic d3 = new MyType (-7);
577                 Assert<MyType> (d3 && new MyType (6), new MyType (0), "#3");
578         }
579
580         void DivideTest ()
581         {
582                 dynamic d = 5;
583
584                 int v = 2;
585                 Assert (d / v, 2, "#1");
586
587                 d = new MyType (5);
588                 MyType v3 = new MyType (30);
589                 Assert (d / v3, new MyType (0), "#3");
590                 dynamic d3 = new MyType (-7);
591                 Assert<MyType> (d3 + new MyType (6), new MyType (-1), "#3a");
592
593                 d = new MyTypeImplicitOnly (6);
594                 decimal v4 = 4m;
595                 Assert (d / v4, 1.5m, "#4");
596         }
597
598         void DivideNullableTest ()
599         {
600                 dynamic d = 5;
601
602                 double? v2 = null;
603                 Assert<double?> (d / v2, null, "#1");
604                 Assert<double?> (d / null, null, "#1a");
605                 Assert<double?> (null / d, null, "#1b");
606
607                 v2 = -2;
608                 Assert (d / v2, -2.5, "#2");
609                 dynamic d2 = (int?) -2;
610                 Assert (d2 / 1, -2, "#2a");
611
612                 d = new MyType (5);
613                 MyType? v3 = new MyType (30);
614                 Assert (d / v3, new MyType (0), "#3");
615                 dynamic d3 = new MyType? (new MyType (-7));
616                 Assert (d3 / new MyType (6), new MyType (-1), "#3a");
617                 Assert<MyType?> (d3 + null, null, "#3b");
618
619                 d = new MyTypeImplicitOnly (5);
620                 decimal? v4 = 4m;
621                 Assert (d / v4, 1.25m, "#4");
622                 v4 = null;
623                 Assert<decimal?> (d / v4, null, "#4a");
624         }
625
626         void DivideCheckedTest ()
627         {
628                 checked {
629                         // TODO:
630                 }
631         }
632
633         void DivideAssignTest ()
634         {
635                 dynamic d = 5;
636
637                 int v = 2;
638                 d /= v;
639                 Assert (d, 2, "#1");
640
641                 d = 5.0;
642                 double v2 = 0.5;
643                 d /= v2;
644                 Assert (d, 10, "#1a");
645                 d /= v;
646                 Assert (d, 5, "#1b");
647
648                 dynamic d3 = new MyType (-7);
649                 d3 /= new MyType (6);
650                 Assert<MyType> (d3, new MyType (-1), "#3");
651
652                 d = 5m;
653                 decimal v4 = 4m;
654                 d /= v4;
655                 Assert (d, 1.25m, "#4");
656         }
657
658         void DivideAssignCheckedTest ()
659         {
660                 checked {
661                         // TODO:
662                 }
663         }
664
665         void ConvertImplicitTest ()
666         {
667                 dynamic d = 3;
668                 decimal v1 = d;
669                 Assert (3m, v1, "#1");
670
671                 d = new MyTypeImplicitOnly (5);
672                 int v2 = d;
673                 Assert (5, v2, "#2");
674
675                 d = (byte) 4;
676                 int v3 = d;
677                 Assert (4, v3, "#3");
678
679                 int[] v4 = new int[] { d };
680                 Assert (4, v4[0], "#4");
681
682                 d = true;
683                 var v5 = new [] { d, 1 };
684                 Assert (true, v5[0], "#5");
685                 Assert (1, v5[1], "#5a");
686
687                 d = "aa";
688                 bool b = false;
689                 var r = b ? d : "ss";
690                 Assert ("ss", r, "#6");
691                 
692                 var v = new [] { d, 1 };
693                 Assert ("aa", v [0], "#7");
694                 
695                 dynamic [,] a = new dynamic [,] { { 1, 2 }, { 'b', 'x' } };
696                 Assert (2, a [0, 1], "#8");
697                 Assert ('x', a [1, 1], "#8a");
698         }
699
700         int ConvertImplicitReturnTest ()
701         {
702                 dynamic d = (byte) 3;
703                 return d;
704         }
705
706         IEnumerable<string> ConvertImplicitReturnTest_2 ()
707         {
708                 dynamic d = "aaa";
709                 yield return d;
710         }
711
712         void ConvertExplicitTest ()
713         {
714                 dynamic d = 300;
715                 Assert (44, (byte) d, "#1");
716                 Assert<byte?> (44, (byte?) d, "#1a");
717
718                 d = 3m;
719                 Assert (3, d, "#2");
720
721                 d = new MyTypeImplicitOnly (5);
722                 Assert (5, (int) d, "#3");
723
724                 d = new MyTypeExplicit (-2);
725                 Assert (-2, (int) d, "#4");
726
727                 d = null;
728                 Assert (null, (object) d, "#5");
729         }
730
731         void ConvertExplicitCheckedTest ()
732         {
733                 checked {
734                         dynamic d = 300;
735                         AssertChecked (() => (byte) d, 7, "#1");
736
737                         d = ulong.MaxValue;
738                         AssertChecked<uint?> (() => (uint?) d, 2, "#2");
739                 }
740         }
741         
742         void ConvertArray ()
743         {
744                 dynamic idx = (uint) 1;
745                 var arr = new int [5];
746                 arr [idx] = 2;
747                 Assert (2, arr [idx], "#1");
748         }
749
750         void EqualTest ()
751         {
752                 dynamic d = 5;
753
754                 int v = 2;
755                 Assert (d == v, false, "#1");
756                 double v2 = 5;
757                 Assert (d == v2, true, "#1a");
758
759                 d = true;
760                 Assert (d == false, false, "#2");
761                 bool b2 = true;
762                 Assert (d == b2, true, "#2a");
763
764                 d = new MyType (30);
765                 MyType v3 = new MyType (30);
766                 Assert (d == v3, true, "#3");
767                 dynamic d3 = new MyTypeImplicitOnly (-7);
768                 Assert (d3 == 11, false, "#3b");
769                 
770                 d = 2m;
771                 decimal v4 = 4m;
772                 Assert (d == v4, false, "#4");
773                 Assert (d == 2m, true, "#4a");
774                 
775                 d = null;
776                 Assert (d == null, true, "#5");
777         }
778
779         void EqualNullableTest ()
780         {
781                 dynamic d = 5;
782
783                 int? v2 = null;
784                 Assert (d == v2, false, "#1");
785                 Assert (d == null, false, "#1a");
786                 Assert (null == d, false, "#1b");
787
788                 v2 = -2;
789                 Assert (d == v2, false, "#2");
790                 dynamic d2 = (int?) -2;
791                 Assert (d2 == 1, false, "#2a");
792                 d2 = (uint?) 44;
793                 Assert (d2 == 44, true, "#2b");
794
795                 d = new MyType (30);
796                 MyType? v3 = new MyType (30);
797                 Assert (d == v3, true, "#3");
798                 dynamic d3 = new MyType? (new MyType (-7));
799                 Assert (d3 == new MyType (6), false, "#3a");
800                 Assert (d3 == null, false, "#3b");
801                 
802                 d = 4.1m;
803                 decimal? v4 = 4m;
804                 Assert (d == v4, false, "#4");
805                 v4 = null;
806                 Assert (d == v4, false, "#4a");
807
808                 d = (bool?) true;
809                 Assert (d == true, true, "#5");
810                 Assert (d == null, false, "#5a");
811                 Assert (d == false, false, "#5b");
812         }
813
814         void EqualEnumTest ()
815         {
816                 dynamic d = MyEnum.Value_1;
817
818                 Assert (d == null, false, "#1");
819
820                 Assert (d == MyEnum.Value_1, true, "#2");
821                 Assert (d == 0, false, "#2a");
822
823                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
824                 Assert (d2 == MyEnumUlong.Value_2, true, "#3");
825                 Assert (d2 == null, false, "#3a");
826         }
827
828         void EqualStringTest ()
829         {
830                 dynamic d = "text";
831
832                 Assert (d == "te", false, "#1");
833                 Assert (d == "text", true, "#1a");
834                 Assert (d == null, false, "#1b");
835         }
836
837         void EqualDelegateTest ()
838         {
839                 dynamic d = this;
840
841 //              Assert (d == delegate { }, true, "#1");
842
843                 EmptyDelegate b = EqualDelegateTest;
844                 d = b;
845
846                 //Assert (d == EqualDelegateTest, true, "#2");
847         
848 /*
849
850         void EqualTestDelegate_2 ()
851         {
852                 EmptyDelegate ed = delegate () {};
853
854                 Expression<Func<EmptyDelegate, EmptyDelegate, bool>> e2 = (a, b) => a == b;
855                 AssertNodeType (e2, ExpressionType.Equal);
856                 Assert (false, e2.Compile ().Invoke (delegate () {}, null));
857                 Assert (false, e2.Compile ().Invoke (delegate () {}, delegate {}));
858                 Assert (false, e2.Compile ().Invoke (ed, delegate {}));
859                 Assert (true, e2.Compile ().Invoke (ed, ed));
860 */
861         }
862
863         void ExclusiveOrTest ()
864         {
865                 dynamic d = true;
866
867                 var v = false;
868                 Assert (d ^ v, true, "#1");
869                 Assert (d ^ true, false, "#1a");
870
871                 d = 42;
872                 var v2 = 62;
873                 Assert (d ^ v2, 20, "#2");
874                 Assert (d ^ 0, 42, "#2a");
875
876                 d = new MyType (42);
877                 MyType v3 = new MyType (30);
878                 Assert (d ^ v3, new MyType (52), "#3");
879                 dynamic d3 = new MyType (-7);
880                 Assert<MyType> (d3 ^ new MyType (6), new MyType (-1), "#3a");
881
882                 d3 = new MyTypeImplicitOnly (-7);
883                 Assert (d3 ^ 11, -14, "#3b");
884         }
885
886         void ExclusiveOrNullableTest ()
887         {
888                 dynamic d = 5;
889
890                 int? v2 = null;
891                 Assert<int?> (d ^ v2, null, "#1");
892                 Assert<int?> (d ^ null, null, "#1a");
893                 Assert<int?> (null ^ d, null, "#1b");
894
895                 v2 = -2;
896                 Assert (d ^ v2, -5, "#2");
897                 dynamic d2 = (int?) -2;
898                 Assert (d2 ^ 1, -1, "#2a");
899
900                 d = new MyType (5);
901                 MyType? v3 = new MyType (30);
902                 Assert (d ^ v3, new MyType (27), "#3");
903                 dynamic d3 = new MyType? (new MyType (-7));
904                 Assert (d3 ^ new MyType (6), new MyType (-1), "#3a");
905                 Assert<MyType?> (d3 ^ null, null, "#3b");
906         }
907
908         void ExclusiveOrTestEnum ()
909         {
910                 dynamic d = MyEnum.Value_1;
911
912                 Assert<MyEnum?> (d ^ null, null, "#1");
913
914                 Assert<MyEnum> (d ^ d, 0, "#2");
915
916                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
917                 Assert<MyEnumUlong> (d2 ^ MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
918         }
919
920         void ExclusiveOrAssignedTest ()
921         {
922                 dynamic d = true;
923
924                 var v = false;
925                 d ^= v;
926                 Assert (d, true, "#1");
927                 d = true;
928                 d ^= true;
929                 Assert (d, false, "#1a");
930
931                 d = 42;
932                 var v2 = 62;
933                 d ^= v2;
934                 Assert (d, 20, "#2");
935
936                 MyType v3 = new MyType (30);
937                 dynamic d3 = new MyType (-7);
938                 d3 ^= new MyType (6);
939                 Assert (d3, new MyType (-1), "#3");
940         }
941
942         void ExclusiveOrAssignedTestEnum ()
943         {
944                 dynamic d = MyEnum.Value_1;
945                 d ^= MyEnum.Value_2;
946                 Assert<MyEnum>(d, (MyEnum) 3, "#1");
947
948                 d = MyEnum.Value_2;
949                 d ^= d;
950                 Assert<MyEnum> (d, 0, "#2");
951
952                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
953                 Assert (d2 ^ MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
954         }
955
956         void GreaterThanTest ()
957         {
958                 dynamic d = 5;
959
960                 int v = 2;
961                 Assert (d > v, true, "#1");
962                 double v2 = 5;
963                 Assert (d > v2, false, "#1a");
964
965                 d = 4.6;
966                 Assert (d > 4.59, true, "#2");
967                 var b2 = 4.6;
968                 Assert (d > b2, false, "#2a");
969
970                 d = new MyType (30);
971                 MyType v3 = new MyType (30);
972                 Assert (d > v3, false, "#3");
973                 dynamic d3 = new MyType (-7);
974                 Assert (d3 > new MyType (6), false, "#3a");
975
976                 d3 = new MyTypeImplicitOnly (-7);
977                 Assert (d3 > 11, false, "#3b");
978
979                 d = 2m;
980                 decimal v4 = 4m;
981                 Assert (d > v4, false, "#4");
982                 Assert (d > 2m, false, "#4a");
983         }
984
985         void GreaterThanNullableTest ()
986         {
987                 dynamic d = 5;
988
989                 int? v2 = null;
990                 Assert (d > v2, false, "#1");
991                 Assert (d > null, false, "#1a");
992                 Assert (null > d, false, "#1b");
993
994                 v2 = -2;
995                 Assert (d > v2, true, "#2");
996                 dynamic d2 = (int?) -2;
997                 Assert (d2 > 1, false, "#2a");
998                 d2 = (uint?) 44;
999                 Assert (d2 > 44, false, "#2b");
1000
1001                 d = new MyType (30);
1002                 MyType? v3 = new MyType (30);
1003                 Assert (d > v3, false, "#3");
1004                 dynamic d3 = new MyType? (new MyType (-7));
1005                 Assert (d3 > new MyType (6), false, "#3a");
1006                 Assert (d3 > null, false, "#3b");
1007
1008                 d = 4.1m;
1009                 decimal? v4 = 4m;
1010                 Assert (d > v4, true, "#4");
1011                 v4 = null;
1012                 Assert (d > v4, false, "#4a");
1013         }
1014
1015         void GreaterThanEnumTest ()
1016         {
1017                 dynamic d = MyEnum.Value_1;
1018
1019                 Assert (d > null, false, "#1");
1020
1021                 Assert (d > MyEnum.Value_1, false, "#2");
1022                 Assert (d > 0, true, "#2a");
1023
1024                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1025                 Assert (d2 > MyEnumUlong.Value_2, false, "#3");
1026                 Assert (d2 > null, false, "#3a");
1027         }
1028
1029         void GreaterThanEqualTest ()
1030         {
1031                 dynamic d = 5;
1032
1033                 int v = 2;
1034                 Assert (d >= v, true, "#1");
1035                 double v2 = 5;
1036                 Assert (d >= v2, true, "#1a");
1037
1038                 d = 4.6;
1039                 Assert (d >= 4.59, true, "#2");
1040                 var b2 = 4.6;
1041                 Assert (d >= b2, true, "#2a");
1042
1043                 d = new MyType (30);
1044                 MyType v3 = new MyType (30);
1045                 Assert (d >= v3, true, "#3");
1046                 dynamic d3 = new MyType (-7);
1047                 Assert (d3 >= new MyType (6), false, "#3a");
1048
1049                 d3 = new MyTypeImplicitOnly (-7);
1050                 Assert (d3 >= 11, false, "#3b");
1051
1052                 d = 2m;
1053                 decimal v4 = 4m;
1054                 Assert (d >= v4, false, "#4");
1055                 Assert (d >= 2m, true, "#4a");
1056         }
1057
1058         void GreaterThanEqualNullableTest ()
1059         {
1060                 dynamic d = 5;
1061
1062                 int? v2 = null;
1063                 Assert (d >= v2, false, "#1");
1064                 Assert (d >= null, false, "#1a");
1065                 Assert (null >= d, false, "#1b");
1066
1067                 v2 = -2;
1068                 Assert (d >= v2, true, "#2");
1069                 dynamic d2 = (int?) -2;
1070                 Assert (d2 >= 1, false, "#2a");
1071                 d2 = (uint?) 44;
1072                 Assert (d2 >= 44, true, "#2b");
1073
1074                 d = new MyType (30);
1075                 MyType? v3 = new MyType (30);
1076                 Assert (d >= v3, true, "#3");
1077                 dynamic d3 = new MyType? (new MyType (-7));
1078                 Assert (d3 >= new MyType (6), false, "#3a");
1079                 Assert (d3 >= null, false, "#3b");
1080
1081                 d = 4.1m;
1082                 decimal? v4 = 4m;
1083                 Assert (d >= v4, true, "#4");
1084                 v4 = null;
1085                 Assert (d >= v4, false, "#4a");
1086         }
1087
1088         void GreaterThanEqualEnumTest ()
1089         {
1090                 dynamic d = MyEnum.Value_1;
1091
1092                 Assert (d >= null, false, "#1");
1093
1094                 Assert (d >= MyEnum.Value_1, true, "#2");
1095                 Assert (d >= 0, true, "#2a");
1096
1097                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1098                 Assert (d2 >= MyEnumUlong.Value_2, true, "#3");
1099                 Assert (d2 >= null, false, "#3a");
1100         }
1101
1102         void LeftShiftTest ()
1103         {
1104                 dynamic d = (ulong) 0x7F000;
1105
1106                 int v = 2;
1107                 Assert<ulong> (d << v, 0x1FC000, "#1");
1108                 Assert<ulong> (d << 1, 0xFE000, "#1a");
1109                 short s = 2;
1110                 Assert<ulong> (d << s, 0x1FC000, "#1b");
1111
1112                 d = 0x7F000;
1113                 MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
1114                 Assert (d << v3, 0x3F8000, "#3");
1115                 dynamic d3 = new MyType (-7);
1116                 Assert (d3 << new MyTypeImplicitOnly (6), -448, "#3a");
1117                 Assert (d3 << 11, -14336, "#3b");
1118         }
1119
1120         void LeftShiftNullableTest ()
1121         {
1122                 dynamic d = 5;
1123
1124                 int? v2 = null;
1125                 Assert<int?> (d << v2, null, "#1");
1126                 d = 5;
1127                 Assert<int?> (d << null, null, "#1a");
1128                 d = 5;
1129                 Assert<int?> (null << d, null, "#1b");
1130
1131                 v2 = -2;
1132                 Assert (d << v2, 0x40000000, "#2");
1133                 dynamic d2 = (int?) -2;
1134                 Assert (d2 << 1, -4, "#2a");
1135
1136                 dynamic d3 = (int?) null;
1137                 Assert (d3 << (null << null), (int?)null, "#3");
1138         }
1139
1140         void LeftShiftAssignTest ()
1141         {
1142                 dynamic d = 0x7F000;
1143
1144                 int v = 2;
1145                 d <<= v;
1146                 Assert (d, 0x1FC000, "#1");
1147                 d <<= 1;
1148                 Assert (d, 0x3F8000, "#1a");
1149                 sbyte s = 2;
1150                 d <<= s;
1151                 Assert (d, 0xFE0000, "#1b");
1152         }
1153
1154         void LeftShiftAssignNullableTest ()
1155         {
1156                 dynamic d = 5;
1157
1158                 var v2 = -2;
1159                 d <<= v2;
1160                 Assert (d, 0x40000000, "#2");
1161                 dynamic d2 = (int?) -2;
1162                 d2 <<= 1;
1163                 Assert (d2, -4, "#2a");
1164         }
1165
1166         void LessThanTest ()
1167         {
1168                 dynamic d = 5;
1169
1170                 int v = 2;
1171                 Assert (d < v, false, "#1");
1172                 double v2 = 5;
1173                 Assert (d < v2, false, "#1a");
1174
1175                 d = 4.6;
1176                 Assert (d < 4.59, false, "#2");
1177                 var b2 = 4.6;
1178                 Assert (d < b2, false, "#2a");
1179
1180                 d = new MyType (30);
1181                 MyType v3 = new MyType (30);
1182                 Assert (d < v3, false, "#3");
1183                 dynamic d3 = new MyType (-7);
1184                 Assert (d3 < new MyType (6), true, "#3a");
1185
1186                 d3 = new MyTypeImplicitOnly (-7);
1187                 Assert (d3 < 11, true, "#3b");
1188
1189                 d = 2m;
1190                 decimal v4 = 4m;
1191                 Assert (d < v4, true, "#4");
1192                 Assert (d < 2m, false, "#4a");
1193         }
1194
1195         void LessThanNullableTest ()
1196         {
1197                 dynamic d = 5;
1198
1199                 int? v2 = null;
1200                 Assert (d < v2, false, "#1");
1201                 Assert (d < null, false, "#1a");
1202                 Assert (null < d, false, "#1b");
1203
1204                 v2 = -2;
1205                 Assert (d < v2, false, "#2");
1206                 dynamic d2 = (int?) -2;
1207                 Assert (d2 < 1, true, "#2a");
1208                 d2 = (uint?) 44;
1209                 Assert (d2 < 44, false, "#2b");
1210
1211                 d = new MyType (30);
1212                 MyType? v3 = new MyType (30);
1213                 Assert (d < v3, false, "#3");
1214                 dynamic d3 = new MyType? (new MyType (-7));
1215                 Assert (d3 < new MyType (6), true, "#3a");
1216
1217                 d3 = new MyTypeImplicitOnly (-7);
1218                 Assert (d3 < null, false, "#3b");
1219
1220                 d = 4.1m;
1221                 decimal? v4 = 4m;
1222                 Assert (d < v4, false, "#4");
1223                 v4 = null;
1224                 Assert (d < v4, false, "#4a");
1225         }
1226
1227         void LessThanEnumTest ()
1228         {
1229                 dynamic d = MyEnum.Value_1;
1230
1231                 Assert (d < null, false, "#1");
1232
1233                 Assert (d < MyEnum.Value_1, false, "#2");
1234                 Assert (d < 0, false, "#2a");
1235
1236                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1237                 Assert (d2 < MyEnumUlong.Value_2, false, "#3");
1238                 Assert (d2 < null, false, "#3a");
1239         }
1240
1241         void LessThanOrEqualTest ()
1242         {
1243                 dynamic d = 5;
1244
1245                 int v = 2;
1246                 Assert (d <= v, false, "#1");
1247                 double v2 = 5;
1248                 Assert (d <= v2, true, "#1a");
1249
1250                 d = 4.6;
1251                 Assert (d <= 4.59, false, "#2");
1252                 var b2 = 4.6;
1253                 Assert (d <= b2, true, "#2a");
1254
1255                 d = new MyType (30);
1256                 MyType v3 = new MyType (30);
1257                 Assert (d <= v3, true, "#3");
1258                 dynamic d3 = new MyType (-7);
1259                 Assert (d3 <= new MyType (6), true, "#3a");
1260
1261                 d3 = new MyTypeImplicitOnly (-7);
1262                 Assert (d3 <= 11, true, "#3b");
1263
1264                 d = 2m;
1265                 decimal v4 = 4m;
1266                 Assert (d <= v4, true, "#4");
1267                 Assert (d <= 2m, true, "#4a");
1268         }
1269
1270         void LessThanOrEqualNullableTest ()
1271         {
1272                 dynamic d = 5;
1273
1274                 int? v2 = null;
1275                 Assert (d <= v2, false, "#1");
1276                 Assert (d <= null, false, "#1a");
1277                 Assert (null <= d, false, "#1b");
1278
1279                 v2 = -2;
1280                 Assert (d <= v2, false, "#2");
1281                 dynamic d2 = (int?) -2;
1282                 Assert (d2 <= 1, true, "#2a");
1283                 d2 = (uint?) 44;
1284                 Assert (d2 <= 44, true, "#2b");
1285
1286                 d = new MyType (30);
1287                 MyType? v3 = new MyType (30);
1288                 Assert (d <= v3, true, "#3");
1289                 dynamic d3 = new MyType? (new MyType (-7));
1290                 Assert (d3 <= new MyType (6), true, "#3a");
1291                 Assert (d3 <= null, false, "#3b");
1292
1293                 d = 4.1m;
1294                 decimal? v4 = 4m;
1295                 Assert (d <= v4, false, "#4");
1296                 v4 = null;
1297                 Assert (d <= v4, false, "#4a");
1298         }
1299
1300         void LessThanOrEqualEnumTest ()
1301         {
1302                 dynamic d = MyEnum.Value_1;
1303
1304                 Assert (d <= null, false, "#1");
1305
1306                 Assert (d <= MyEnum.Value_1, true, "#2");
1307                 Assert (d <= 0, false, "#2a");
1308
1309                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1310                 Assert (d2 <= MyEnumUlong.Value_2, true, "#3");
1311                 Assert (d2 <= null, false, "#3a");
1312         }
1313
1314         void ModuloTest ()
1315         {
1316                 dynamic d = 5;
1317
1318                 int v = 2;
1319                 Assert (d % v, 1, "#1");
1320
1321                 d = new MyType (5);
1322                 MyType v3 = new MyType (30);
1323                 Assert (d % v3, new MyType (5), "#3");
1324                 dynamic d3 = new MyType (-7);
1325                 Assert<MyType> (d3 % new MyType (6), new MyType (-1), "#3a");
1326
1327                 d = new MyTypeImplicitOnly (5);
1328                 decimal v4 = 4m;
1329                 Assert (d % v4, 1m, "#4");
1330         }
1331
1332         void ModuloNullableTest ()
1333         {
1334                 dynamic d = 5;
1335
1336                 double? v2 = null;
1337                 Assert<double?> (d % v2, null, "#1");
1338                 Assert<double?> (d % null, null, "#1a");
1339                 Assert<double?> (null % d, null, "#1b");
1340
1341                 v2 = -2;
1342                 Assert (d % v2, 1, "#2");
1343                 dynamic d2 = (int?) -2;
1344                 Assert (d2 % 1, 0, "#2a");
1345
1346                 d = new MyType (-2);
1347                 MyType? v3 = new MyType (30);
1348                 Assert (d % v3, new MyType (-2), "#3");
1349                 dynamic d3 = new MyType? (new MyType (-7));
1350                 Assert (d3 % new MyType (6), new MyType (-1), "#3a");
1351                 Assert<MyType?> (d3 + null, null, "#3b");
1352
1353                 d = new MyTypeImplicitOnly (5);
1354                 decimal? v4 = 4m;
1355                 Assert (d % v4, 1m, "#4");
1356                 v4 = null;
1357                 Assert<decimal?> (d % v4, null, "#4a");
1358         }
1359
1360         void ModuloAssignTest ()
1361         {
1362                 dynamic d = 5;
1363
1364                 int v = 2;
1365                 d %= v;
1366                 Assert (d, 1, "#1");
1367
1368                 d = 5.0;
1369                 double v2 = 0.5;
1370                 d %= v2;
1371                 Assert (d, 0, "#1a");
1372                 d %= v;
1373                 Assert (d, 0, "#1b");
1374
1375                 dynamic d3 = new MyType (-7);
1376                 d3 %= new MyType (6);
1377                 Assert<MyType> (d3, new MyType (-1), "#3");
1378
1379                 d = 5m;
1380                 decimal v4 = 4m;
1381                 d %= v4;
1382                 Assert (d, 1m, "#4");
1383         }
1384
1385         void MultiplyTest ()
1386         {
1387                 dynamic d = 5;
1388
1389                 int v = 2;
1390                 Assert (d * v, 10, "#1");
1391                 double v2 = 0.5;
1392                 Assert (d * v2, 2.5, "#1a");
1393
1394                 d = new MyType (5);
1395                 MyType v3 = new MyType (30);
1396                 Assert (d * v3, new MyType (150), "#3");
1397                 dynamic d3 = new MyType (-7);
1398                 Assert<MyType> (d3 * new MyType (6), new MyType (-42), "#3a");
1399
1400                 decimal v4 = 4m;
1401                 d = 7.9m;
1402                 Assert (d * v4, 31.6m, "#4");
1403         }
1404
1405         void MultiplyNullableTest ()
1406         {
1407                 dynamic d = 5;
1408
1409                 int? v2 = null;
1410                 Assert<int?> (d * v2, null, "#1");
1411                 Assert<int?> (d * null, null, "#1a");
1412                 Assert<int?> (null * d, null, "#1b");
1413
1414                 v2 = -2;
1415                 Assert (d * v2, -10, "#2");
1416                 dynamic d2 = (int?) -2;
1417                 Assert (d2 * 1, -2, "#2a");
1418
1419                 d = new MyType (5);
1420                 MyType? v3 = new MyType (30);
1421                 Assert (d * v3, new MyType (150), "#3");
1422                 dynamic d3 = new MyType? (new MyType (-7));
1423                 Assert (d3 * new MyType (6), new MyType (-42), "#3a");
1424                 Assert<MyType?> (d3 * null, null, "#3b");
1425
1426                 d = new MyTypeImplicitOnly (5);
1427                 decimal? v4 = 4m;
1428                 Assert (d * v4, 20m, "#4");
1429                 v4 = null;
1430                 Assert<decimal?> (d * v4, null, "#4a");
1431         }
1432
1433         void MultiplyCheckedTest ()
1434         {
1435                 checked {
1436                         dynamic d = 5;
1437
1438                         int v = int.MaxValue;
1439                         AssertChecked (() => d * v, 7, "#1");
1440
1441                         int? v2 = v;
1442                         AssertChecked (() => d * v2, null, "#2");
1443
1444                         d = new MyType (4);
1445                         MyType v3 = new MyType (int.MaxValue);
1446                         Assert (d * v3, new MyType (-4), "#3");
1447                 }
1448         }
1449
1450         void MultiplyAssignTest ()
1451         {
1452                 dynamic d = 5;
1453
1454                 int v = 2;
1455                 d *= v;
1456                 Assert (d, 10, "#1");
1457
1458                 d = 5.0;
1459                 double v2 = 0.5;
1460                 d *= v2;
1461                 Assert (d, 2.5, "#1a");
1462                 d *= v;
1463                 Assert (d, 5, "#1b");
1464
1465                 dynamic d3 = new MyType (-7);
1466                 d3 *= new MyType (6);
1467                 Assert<MyType> (d3, new MyType (-42), "#3");
1468
1469                 d = 5m;
1470                 decimal v4 = 4m;
1471                 d *= v4;
1472                 Assert (d, 20m, "#4");
1473                 
1474                 int i = 3;
1475                 d = 5;
1476                 i *= d;
1477                 Assert (i, 15, "#5");
1478         }
1479
1480         void MultiplyAssignCheckedTest ()
1481         {
1482                 checked {
1483                         dynamic d = 5;
1484
1485                         int v = int.MaxValue;
1486                         AssertChecked (() => { d *= v; Assert (d, 0, "#1-"); }, "#1");
1487
1488                         d = new MyType (44);
1489                         MyType v3 = new MyType (int.MaxValue);
1490                         d *= v3;
1491                         Assert (d, new MyType (-44), "#3-");
1492                 }
1493         }
1494
1495         void Negate ()
1496         {
1497                 dynamic d = -8;
1498                 Assert (8, -d, "#1");
1499                 Assert (-8, -(-d), "#1a");
1500
1501                 d = new MyType (-14);
1502                 Assert (new MyType (14), -d, "#2");
1503
1504                 d = new MyTypeImplicitOnly (4);
1505                 Assert (-4, -d, "#3");
1506
1507                 d = (uint) 7;
1508                 Assert (-7, -d, "#4");
1509
1510                 d = double.NegativeInfinity;
1511                 Assert (double.PositiveInfinity, -d, "#5");
1512         }
1513
1514         void NegateNullable ()
1515         {
1516                 dynamic d = (int?) -8;
1517                 Assert (8, -d, "#1");
1518                 Assert (-8, -(-d), "#1a");
1519
1520                 MyType? n1 = new MyType (4);
1521                 d = n1;
1522                 Assert (new MyType (-4), -d, "#2");
1523
1524                 MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
1525                 d = n2;
1526                 Assert (-4, -d, "#3");
1527
1528                 d = (sbyte?) 7;
1529                 Assert (-7, -d, "#4");
1530         }
1531
1532         void NegateChecked ()
1533         {
1534                 checked {
1535                         dynamic d = int.MinValue;
1536                         AssertChecked (() => -d, 0, "#1");
1537                 }
1538         }
1539
1540         void Not ()
1541         {
1542                 dynamic d = true;
1543                 Assert (false, !d, "#1");
1544
1545                 var de = new MyType (-1);
1546                 Assert (false, !d, "#2");
1547         }
1548
1549         void NotEqualTest ()
1550         {
1551                 dynamic d = 5;
1552
1553                 int v = 2;
1554                 Assert (d != v, true, "#1");
1555                 double v2 = 5;
1556                 Assert (d != v2, false, "#1a");
1557
1558                 d = true;
1559                 Assert (d != false, true, "#2");
1560                 bool b2 = true;
1561                 Assert (d != b2, false, "#2a");
1562
1563                 d = new MyType (30);
1564                 MyType v3 = new MyType (30);
1565                 Assert (d != v3, false, "#3");
1566                 dynamic d3 = new MyType (-7);
1567                 Assert (d3 != new MyType (6), true, "#3a");
1568
1569                 d = 2m;
1570                 decimal v4 = 4m;
1571                 Assert (d != v4, true, "#4");
1572                 Assert (d != 2m, false, "#4a");
1573
1574                 d = null;
1575                 Assert (d != null, false, "#5");
1576         }
1577
1578         void NotEqualNullableTest ()
1579         {
1580                 dynamic d = 5;
1581
1582                 int? v2 = null;
1583                 Assert (d != v2, true, "#1");
1584                 Assert (d != null, true, "#1a");
1585                 Assert (null != d, true, "#1b");
1586
1587                 v2 = -2;
1588                 Assert (d != v2, true, "#2");
1589                 dynamic d2 = (int?) -2;
1590                 Assert (d2 != 1, true, "#2a");
1591                 d2 = (uint?) 44;
1592                 Assert (d2 != 44, false, "#2b");
1593
1594                 d = new MyType (30);
1595                 MyType? v3 = new MyType (30);
1596                 Assert (d != v3, false, "#3");
1597                 dynamic d3 = new MyType? (new MyType (-7));
1598                 Assert (d3 != new MyType (6), true, "#3a");
1599                 Assert (d3 != null, true, "#3b");
1600
1601                 d = 4.1m;
1602                 decimal? v4 = 4m;
1603                 Assert (d != v4, true, "#4");
1604                 v4 = null;
1605                 Assert (d != v4, true, "#4a");
1606
1607                 d = (bool?) true;
1608                 Assert (d != true, false, "#5");
1609                 Assert (d != null, true, "#5a");
1610                 Assert (d != false, true, "#5b");
1611         }
1612
1613         void NotEqualEnumTest ()
1614         {
1615                 dynamic d = MyEnum.Value_1;
1616
1617                 Assert (d != null, true, "#1");
1618
1619                 Assert (d != MyEnum.Value_1, false, "#2");
1620                 Assert (d != 0, true, "#2a");
1621
1622                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1623                 Assert (d2 != MyEnumUlong.Value_2, false, "#3");
1624                 Assert (d2 != null, true, "#3a");
1625         }
1626
1627         void NotEqualStringTest ()
1628         {
1629                 dynamic d = "text";
1630
1631                 Assert (d != "te", true, "#1");
1632                 Assert (d != "text", false, "#1a");
1633                 Assert (d != null, true, "#1b");
1634         }
1635
1636         void OnesComplement ()
1637         {
1638                 dynamic d = 7;
1639                 Assert (-8, ~d, "#1");
1640
1641                 d = new MyType (-1);
1642                 Assert (0, ~d, "#2");
1643
1644                 d = (ulong) 7;
1645                 Assert (18446744073709551608, ~d, "#3");
1646
1647                 d = MyEnum.Value_1;
1648                 Assert ((MyEnum) 254, ~d, "#4");
1649         }
1650
1651         void OnesComplementNullable ()
1652         {
1653                 dynamic d = (int?) 7;
1654                 Assert (-8, ~d, "#1");
1655
1656                 d = (MyEnum?) MyEnum.Value_1;
1657                 Assert ((MyEnum) 254, ~d, "#4");
1658         }
1659
1660         void OrTest ()
1661         {
1662                 dynamic d = true;
1663
1664                 var v = false;
1665                 Assert (d | v, true, "#1");
1666                 Assert (d | false, true, "#1a");
1667
1668                 d = 42;
1669                 var v2 = 62;
1670                 Assert (d | v2, 62, "#2");
1671                 Assert (d | 0, 42, "#2a");
1672
1673                 d = new MyType (42);
1674                 MyType v3 = new MyType (30);
1675                 Assert (d | v3, new MyType (62), "#3");
1676                 dynamic d3 = new MyType (-7);
1677                 Assert<MyType> (d3 | new MyType (6), new MyType (-1), "#3a");
1678
1679                 d3 = new MyTypeImplicitOnly (-7);
1680                 Assert (d3 | 11, -5, "#3b");
1681         }
1682
1683         void OrTestEnum ()
1684         {
1685                 dynamic d = MyEnum.Value_1;
1686
1687                 Assert<MyEnum?> (d | null, null, "#1");
1688
1689                 Assert (d | d, MyEnum.Value_1, "#2");
1690
1691                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1692                 Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
1693         }
1694
1695         void OrTestNullable ()
1696         {
1697                 dynamic d = 5;
1698
1699                 int? v2 = null;
1700                 Assert<int?> (d | v2, null, "#1");
1701                 Assert<int?> (d | null, null, "#1a");
1702                 Assert<int?> (null | d, null, "#1b");
1703
1704                 v2 = -2;
1705                 Assert (d | v2, -1, "#2");
1706                 dynamic d2 = (int?) -2;
1707                 Assert (d2 | 1, -1, "#2a");
1708
1709                 d = new MyType (-2);
1710                 MyType? v3 = new MyType (30);
1711                 Assert (d | v3, new MyType (-2), "#3");
1712                 dynamic d3 = new MyType? (new MyType (-7));
1713                 Assert (d3 | new MyType (6), new MyType (-1), "#3a");
1714         }
1715
1716         void OrAssignedTest ()
1717         {
1718                 dynamic d = true;
1719
1720                 var v = false;
1721                 d |= v;
1722                 Assert (d, true, "#1");
1723                 d = true;
1724                 d |= true;
1725                 Assert (d, true, "#1a");
1726
1727                 d = 42;
1728                 var v2 = 62;
1729                 d |= v2;
1730                 Assert (d, 62, "#2");
1731
1732                 MyType v3 = new MyType (30);
1733                 dynamic d3 = new MyType (-7);
1734                 d3 |= new MyType (6);
1735                 Assert<MyType> (d3, new MyType (-1), "#3");
1736         }
1737
1738         void OrAssignedTestEnum ()
1739         {
1740                 dynamic d = MyEnum.Value_1;
1741                 d |= MyEnum.Value_2;
1742                 Assert<MyEnum> (d, (MyEnum) 3, "#1");
1743
1744                 d = MyEnum.Value_2;
1745                 d |= d;
1746                 Assert (d, MyEnum.Value_2, "#2");
1747
1748                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1749                 Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
1750         }
1751
1752         void OrElseTest ()
1753         {
1754                 dynamic d = true;
1755
1756                 var v = false;
1757                 Assert<bool> (d || v, true, "#1");
1758
1759                 Assert (d || true, true, "#1a");
1760
1761                 d = true;
1762                 Assert (d || d, true, "#2");
1763
1764                 dynamic d3 = new MyType (-7);
1765                 Assert<MyType> (d3 || new MyType (6), new MyType (-7), "#3");
1766         }
1767
1768         void RightShiftTest ()
1769         {
1770                 dynamic d = (ulong) 0x7F000;
1771
1772                 int v = 2;
1773                 Assert<ulong> (d >> v, 0x1FC00, "#1");
1774                 Assert<ulong> (d >> 1, 0x3F800, "#1a");
1775                 short s = 2;
1776                 Assert<ulong> (d >> s, 0x1FC00, "#1b");
1777
1778                 d = 0x7F000;
1779                 MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
1780                 Assert (d >> v3, 0xFE00, "#3");
1781                 dynamic d3 = new MyType (-7);
1782                 Assert (d3 >> new MyTypeImplicitOnly (11), -1, "#3a");
1783         }
1784
1785         void RightShiftNullableTest ()
1786         {
1787                 dynamic d = 5;
1788
1789                 int? v2 = null;
1790                 Assert<int?> (d >> v2, null, "#1");
1791                 d = 5;
1792                 Assert<int?> (d >> null, null, "#1a");
1793                 d = 5;
1794                 Assert<int?> (null >> d, null, "#1b");
1795
1796                 v2 = -2;
1797                 Assert (d >> v2, 0, "#2");
1798                 dynamic d2 = (int?) -200;
1799                 Assert (d2 >> 1, -100, "#2a");
1800
1801                 dynamic d3 = (int?) null;
1802                 Assert (d3 >> (null >> null), (int?) null, "#3");
1803         }
1804
1805         void RightShiftAssignTest ()
1806         {
1807                 dynamic d = 0x7F000;
1808
1809                 int v = 2;
1810                 d >>= v;
1811                 Assert (d, 0x1FC00, "#1");
1812                 d >>= 1;
1813                 Assert (d, 0xFE00, "#1a");
1814                 sbyte s = 2;
1815                 d >>= s;
1816                 Assert (d, 0x3F80, "#1b");
1817         }
1818
1819         void RightShiftAssignNullableTest ()
1820         {
1821                 dynamic d = 0x2A0;
1822
1823                 var v2 = -2;
1824                 d >>= v2;
1825                 Assert (d, 0, "#2");
1826                 dynamic d2 = (int?) -2;
1827                 d2 >>= 1;
1828                 Assert (d2, -1, "#2a");
1829         }
1830
1831         void SubtractTest ()
1832         {
1833                 dynamic d = 5;
1834
1835                 int v = 2;
1836                 Assert (d - v, 3, "#1");
1837                 double v2 = 0.5;
1838                 Assert (d - v2, 4.5, "#1a");
1839
1840                 d = new MyType (5);
1841                 MyType v3 = new MyType (30);
1842                 Assert (d - v3, new MyType (-25), "#3");
1843                 dynamic d3 = new MyType (-7);
1844                 Assert (d3 - new MyType (6), new MyType (-13), "#3a");
1845
1846                 d = new MyTypeImplicitOnly (5);
1847                 decimal v4 = 4m;
1848                 Assert (d - v4, 1m, "#4");
1849         }
1850
1851         void SubtractNullableTest ()
1852         {
1853                 dynamic d = 5;
1854
1855                 int? v2 = null;
1856                 Assert<int?> (d - v2, null, "#1");
1857                 Assert<int?> (d - null, null, "#1a");
1858                 Assert<int?> (null - d, null, "#1b");
1859
1860                 v2 = -2;
1861                 Assert (d - v2, 7, "#2");
1862                 dynamic d2 = (int?) -2;
1863                 Assert (d2 - 1, -3, "#2a");
1864
1865                 d = new MyType (5);
1866                 MyType? v3 = new MyType (30);
1867                 Assert (d - v3, new MyType (-25), "#3");
1868                 dynamic d3 = new MyType? (new MyType (-7));
1869                 Assert (d3 - new MyType (6), new MyType (-13), "#3a");
1870                 Assert<MyType?> (d3 - null, null, "#3b");
1871
1872                 d = new MyTypeImplicitOnly (5);
1873                 decimal? v4 = 4m;
1874                 Assert (d - v4, 1m, "#4");
1875                 v4 = null;
1876                 Assert<decimal?> (d - v4, null, "#4a");
1877         }
1878
1879         void SubtractEnumTest ()
1880         {
1881                 dynamic d = MyEnum.Value_1;
1882
1883                 Assert<MyEnum> (d - 1, 0, "#1");
1884
1885                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1886                 Assert (d2 - (byte) 1, MyEnumUlong.Value_1, "#2");
1887                 Assert<MyEnumUlong?> (d2 - null, null, "#2a");
1888                 
1889                 // CSC: Invalid System.InvalidOperationException
1890                 Assert<MyEnum?> (d - null, null, "#3");
1891         }
1892
1893         void SubtractCheckedTest ()
1894         {
1895                 checked {
1896                         dynamic d = 5;
1897
1898                         int v = int.MinValue;
1899                         AssertChecked (() => d - v, 7, "#1");
1900
1901                         int? v2 = v;
1902                         AssertChecked (() => d - v2, null, "#2");
1903
1904                         d = new MyType (5);
1905                         MyType v3 = new MyType (int.MinValue);
1906                         Assert (d - v3, new MyType (-2147483643), "#3");
1907                 }
1908         }
1909
1910         void SubtractAssignTest ()
1911         {
1912                 dynamic d = 5;
1913
1914                 int v = 2;
1915                 d -= v;
1916                 Assert (d, 3, "#1");
1917
1918                 d = 5.0;
1919                 double v2 = 0.5;
1920                 d -= v2;
1921                 Assert (d, 4.5, "#1a");
1922                 d -= v;
1923                 Assert (d, 2.5, "#1b");
1924
1925                 dynamic d3 = new MyType (-7);
1926                 d3 -= new MyType (6);
1927                 Assert<MyType> (d3, new MyType (-13), "#3");
1928
1929                 d = 5m;
1930                 decimal v4 = 4m;
1931                 d -= v4;
1932                 Assert (d, 1m, "#4");
1933         }
1934
1935         void SubtractAssignEnumTest ()
1936         {
1937                 dynamic d = MyEnum.Value_1;
1938
1939                 d -= 1;
1940                 Assert<MyEnum> (d, 0, "#2");
1941
1942                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1943                 d2 -= (byte) 1;
1944                 Assert (d2, MyEnumUlong.Value_1, "#3");
1945         }
1946
1947         void SubtractAssignCheckedTest ()
1948         {
1949                 checked {
1950                         dynamic d = 5;
1951
1952                         int v = int.MinValue;
1953                         AssertChecked (() => { d -= v; Assert (d, 0, "#1a"); }, "#1");
1954
1955                         d = new MyType (5);
1956                         MyType v3 = new MyType (int.MinValue);
1957                         d -= v3;
1958                         Assert (d, new MyType (-2147483643), "#3a");
1959                 }
1960         }
1961
1962         void SubtractAssignEvent ()
1963         {
1964                 Action print = () => { Console.WriteLine ("foo"); };
1965                 dynamic d = print;
1966                 
1967                 // FIXME: Will have to special case events
1968                 //ev_assign -= d;
1969                 //ev_assign ();
1970         }
1971
1972         void UnaryDecrement ()
1973         {
1974                 dynamic d = 3;
1975                 Assert (3, d--, "#1");
1976                 Assert (2, d, "#1a");
1977
1978                 d = 3;
1979                 Assert (2, --d, "#2");
1980                 Assert (2, d, "#2a");
1981
1982                 d = new MyType (-3);
1983                 Assert (new MyType (-3), d--, "#3");
1984                 Assert (new MyType (-1), d, "#3a");
1985         }
1986
1987         void UnaryDecrementCheckedTest ()
1988         {
1989                 checked {
1990                         dynamic d = int.MinValue;
1991
1992                         AssertChecked (() => { d--; Assert (d, -1073741824, "#1a"); }, "#1");
1993
1994                         d = new MyType (int.MinValue);
1995                         d--;
1996                         Assert (d, new MyType (-1073741824), "#2");
1997                 }
1998         }
1999
2000         void UnaryIncrement ()
2001         {
2002                 dynamic d = 3;
2003                 Assert (3, d++, "#1");
2004                 Assert (4, d, "#1a");
2005
2006                 d = 3;
2007                 Assert (4, ++d, "#2");
2008                 Assert (4, d, "#2a");
2009
2010                 d = new MyType (-3);
2011                 Assert (new MyType (-3), d++, "#3");
2012                 Assert (new MyType (-6), d, "#3a");
2013         }
2014
2015         void UnaryIncrementCheckedTest ()
2016         {
2017                 checked {
2018                         dynamic d = int.MaxValue;
2019
2020                         AssertChecked (() => { d++; Assert (d, 0, "#1a"); }, "#1");
2021
2022                         d = new MyType (int.MaxValue);
2023                         d++;
2024                         Assert (d, new MyType (-2), "#2");
2025                 }
2026         }
2027
2028         //void UnaryIsFalse ()
2029         //{
2030         //    dynamic d = this;
2031         //    object r = d == null;
2032         //    Assert (false, (bool) r, "#1");
2033         //    Assert<object> (true, d != null, "#1a");
2034         //}
2035
2036         void UnaryIsTrue ()
2037         {
2038                 dynamic d = true;
2039                 Assert (3, d ? 3 : 5, "#1");
2040
2041                 d = 4;
2042                 Assert (false, d < 1, "#2");
2043
2044                 d = new InverseLogicalOperator (true);
2045                 Assert (1, d ? 1 : -1, "#3");
2046         }
2047
2048         void UnaryPlus ()
2049         {
2050                 dynamic d = -8;
2051                 Assert (-8, +d, "#1");
2052                 Assert (-8, +(+d), "#1a");
2053
2054                 d = new MyType (14);
2055                 Assert (new MyType (334455), +d, "#2");
2056
2057                 d = new MyTypeImplicitOnly (4);
2058                 Assert (4, +d, "#3");
2059
2060                 d = (uint) 7;
2061                 Assert<uint> (7, +d, "#4");
2062         }
2063
2064         void UnaryPlusNullable ()
2065         {
2066                 dynamic d = (int?) -8;
2067                 Assert (-8, +d, "#1");
2068                 Assert (-8, +(+d), "#1a");
2069
2070                 MyType? n1 = new MyType (4);
2071                 d = n1;
2072                 Assert (new MyType (334455), +d, "#2");
2073
2074                 MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
2075                 d = n2;
2076                 Assert (4, +d, "#3");
2077
2078                 d = (sbyte?) 7;
2079                 Assert (7, +d, "#4");
2080         }
2081
2082 #pragma warning restore 169
2083
2084         static bool RunTest (MethodInfo test)
2085         {
2086                 Console.Write ("Running test {0, -25}", test.Name);
2087                 try {
2088                         test.Invoke (new Tester (), null);
2089                         Console.WriteLine ("OK");
2090                         return true;
2091                 } catch (Exception e) {
2092                         Console.WriteLine ("FAILED");
2093                         Console.WriteLine (e.ToString ());
2094                         return false;
2095                 }
2096         }
2097
2098         public static int Main ()
2099         {
2100                 var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
2101                                         where test.GetParameters ().Length == 0
2102                                         orderby test.Name
2103                                         select RunTest (test);
2104
2105                 int failures = tests.Count (a => !a);
2106                 Console.WriteLine (failures + " tests failed");
2107                 return failures;
2108         }
2109 }
2110