Bug 15572. Lookup KnownTypeCollection element types in MSSimpleNamespace
[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
1137         void LeftShiftAssignTest ()
1138         {
1139                 dynamic d = 0x7F000;
1140
1141                 int v = 2;
1142                 d <<= v;
1143                 Assert (d, 0x1FC000, "#1");
1144                 d <<= 1;
1145                 Assert (d, 0x3F8000, "#1a");
1146                 sbyte s = 2;
1147                 d <<= s;
1148                 Assert (d, 0xFE0000, "#1b");
1149         }
1150
1151         void LeftShiftAssignNullableTest ()
1152         {
1153                 dynamic d = 5;
1154
1155                 var v2 = -2;
1156                 d <<= v2;
1157                 Assert (d, 0x40000000, "#2");
1158                 dynamic d2 = (int?) -2;
1159                 d2 <<= 1;
1160                 Assert (d2, -4, "#2a");
1161         }
1162
1163         void LessThanTest ()
1164         {
1165                 dynamic d = 5;
1166
1167                 int v = 2;
1168                 Assert (d < v, false, "#1");
1169                 double v2 = 5;
1170                 Assert (d < v2, false, "#1a");
1171
1172                 d = 4.6;
1173                 Assert (d < 4.59, false, "#2");
1174                 var b2 = 4.6;
1175                 Assert (d < b2, false, "#2a");
1176
1177                 d = new MyType (30);
1178                 MyType v3 = new MyType (30);
1179                 Assert (d < v3, false, "#3");
1180                 dynamic d3 = new MyType (-7);
1181                 Assert (d3 < new MyType (6), true, "#3a");
1182
1183                 d3 = new MyTypeImplicitOnly (-7);
1184                 Assert (d3 < 11, true, "#3b");
1185
1186                 d = 2m;
1187                 decimal v4 = 4m;
1188                 Assert (d < v4, true, "#4");
1189                 Assert (d < 2m, false, "#4a");
1190         }
1191
1192         void LessThanNullableTest ()
1193         {
1194                 dynamic d = 5;
1195
1196                 int? v2 = null;
1197                 Assert (d < v2, false, "#1");
1198                 Assert (d < null, false, "#1a");
1199                 Assert (null < d, false, "#1b");
1200
1201                 v2 = -2;
1202                 Assert (d < v2, false, "#2");
1203                 dynamic d2 = (int?) -2;
1204                 Assert (d2 < 1, true, "#2a");
1205                 d2 = (uint?) 44;
1206                 Assert (d2 < 44, false, "#2b");
1207
1208                 d = new MyType (30);
1209                 MyType? v3 = new MyType (30);
1210                 Assert (d < v3, false, "#3");
1211                 dynamic d3 = new MyType? (new MyType (-7));
1212                 Assert (d3 < new MyType (6), true, "#3a");
1213
1214                 d3 = new MyTypeImplicitOnly (-7);
1215                 Assert (d3 < null, false, "#3b");
1216
1217                 d = 4.1m;
1218                 decimal? v4 = 4m;
1219                 Assert (d < v4, false, "#4");
1220                 v4 = null;
1221                 Assert (d < v4, false, "#4a");
1222         }
1223
1224         void LessThanEnumTest ()
1225         {
1226                 dynamic d = MyEnum.Value_1;
1227
1228                 Assert (d < null, false, "#1");
1229
1230                 Assert (d < MyEnum.Value_1, false, "#2");
1231                 Assert (d < 0, false, "#2a");
1232
1233                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1234                 Assert (d2 < MyEnumUlong.Value_2, false, "#3");
1235                 Assert (d2 < null, false, "#3a");
1236         }
1237
1238         void LessThanOrEqualTest ()
1239         {
1240                 dynamic d = 5;
1241
1242                 int v = 2;
1243                 Assert (d <= v, false, "#1");
1244                 double v2 = 5;
1245                 Assert (d <= v2, true, "#1a");
1246
1247                 d = 4.6;
1248                 Assert (d <= 4.59, false, "#2");
1249                 var b2 = 4.6;
1250                 Assert (d <= b2, true, "#2a");
1251
1252                 d = new MyType (30);
1253                 MyType v3 = new MyType (30);
1254                 Assert (d <= v3, true, "#3");
1255                 dynamic d3 = new MyType (-7);
1256                 Assert (d3 <= new MyType (6), true, "#3a");
1257
1258                 d3 = new MyTypeImplicitOnly (-7);
1259                 Assert (d3 <= 11, true, "#3b");
1260
1261                 d = 2m;
1262                 decimal v4 = 4m;
1263                 Assert (d <= v4, true, "#4");
1264                 Assert (d <= 2m, true, "#4a");
1265         }
1266
1267         void LessThanOrEqualNullableTest ()
1268         {
1269                 dynamic d = 5;
1270
1271                 int? v2 = null;
1272                 Assert (d <= v2, false, "#1");
1273                 Assert (d <= null, false, "#1a");
1274                 Assert (null <= d, false, "#1b");
1275
1276                 v2 = -2;
1277                 Assert (d <= v2, false, "#2");
1278                 dynamic d2 = (int?) -2;
1279                 Assert (d2 <= 1, true, "#2a");
1280                 d2 = (uint?) 44;
1281                 Assert (d2 <= 44, true, "#2b");
1282
1283                 d = new MyType (30);
1284                 MyType? v3 = new MyType (30);
1285                 Assert (d <= v3, true, "#3");
1286                 dynamic d3 = new MyType? (new MyType (-7));
1287                 Assert (d3 <= new MyType (6), true, "#3a");
1288                 Assert (d3 <= null, false, "#3b");
1289
1290                 d = 4.1m;
1291                 decimal? v4 = 4m;
1292                 Assert (d <= v4, false, "#4");
1293                 v4 = null;
1294                 Assert (d <= v4, false, "#4a");
1295         }
1296
1297         void LessThanOrEqualEnumTest ()
1298         {
1299                 dynamic d = MyEnum.Value_1;
1300
1301                 Assert (d <= null, false, "#1");
1302
1303                 Assert (d <= MyEnum.Value_1, true, "#2");
1304                 Assert (d <= 0, false, "#2a");
1305
1306                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1307                 Assert (d2 <= MyEnumUlong.Value_2, true, "#3");
1308                 Assert (d2 <= null, false, "#3a");
1309         }
1310
1311         void ModuloTest ()
1312         {
1313                 dynamic d = 5;
1314
1315                 int v = 2;
1316                 Assert (d % v, 1, "#1");
1317
1318                 d = new MyType (5);
1319                 MyType v3 = new MyType (30);
1320                 Assert (d % v3, new MyType (5), "#3");
1321                 dynamic d3 = new MyType (-7);
1322                 Assert<MyType> (d3 % new MyType (6), new MyType (-1), "#3a");
1323
1324                 d = new MyTypeImplicitOnly (5);
1325                 decimal v4 = 4m;
1326                 Assert (d % v4, 1m, "#4");
1327         }
1328
1329         void ModuloNullableTest ()
1330         {
1331                 dynamic d = 5;
1332
1333                 double? v2 = null;
1334                 Assert<double?> (d % v2, null, "#1");
1335                 Assert<double?> (d % null, null, "#1a");
1336                 Assert<double?> (null % d, null, "#1b");
1337
1338                 v2 = -2;
1339                 Assert (d % v2, 1, "#2");
1340                 dynamic d2 = (int?) -2;
1341                 Assert (d2 % 1, 0, "#2a");
1342
1343                 d = new MyType (-2);
1344                 MyType? v3 = new MyType (30);
1345                 Assert (d % v3, new MyType (-2), "#3");
1346                 dynamic d3 = new MyType? (new MyType (-7));
1347                 Assert (d3 % new MyType (6), new MyType (-1), "#3a");
1348                 Assert<MyType?> (d3 + null, null, "#3b");
1349
1350                 d = new MyTypeImplicitOnly (5);
1351                 decimal? v4 = 4m;
1352                 Assert (d % v4, 1m, "#4");
1353                 v4 = null;
1354                 Assert<decimal?> (d % v4, null, "#4a");
1355         }
1356
1357         void ModuloAssignTest ()
1358         {
1359                 dynamic d = 5;
1360
1361                 int v = 2;
1362                 d %= v;
1363                 Assert (d, 1, "#1");
1364
1365                 d = 5.0;
1366                 double v2 = 0.5;
1367                 d %= v2;
1368                 Assert (d, 0, "#1a");
1369                 d %= v;
1370                 Assert (d, 0, "#1b");
1371
1372                 dynamic d3 = new MyType (-7);
1373                 d3 %= new MyType (6);
1374                 Assert<MyType> (d3, new MyType (-1), "#3");
1375
1376                 d = 5m;
1377                 decimal v4 = 4m;
1378                 d %= v4;
1379                 Assert (d, 1m, "#4");
1380         }
1381
1382         void MultiplyTest ()
1383         {
1384                 dynamic d = 5;
1385
1386                 int v = 2;
1387                 Assert (d * v, 10, "#1");
1388                 double v2 = 0.5;
1389                 Assert (d * v2, 2.5, "#1a");
1390
1391                 d = new MyType (5);
1392                 MyType v3 = new MyType (30);
1393                 Assert (d * v3, new MyType (150), "#3");
1394                 dynamic d3 = new MyType (-7);
1395                 Assert<MyType> (d3 * new MyType (6), new MyType (-42), "#3a");
1396
1397                 decimal v4 = 4m;
1398                 d = 7.9m;
1399                 Assert (d * v4, 31.6m, "#4");
1400         }
1401
1402         void MultiplyNullableTest ()
1403         {
1404                 dynamic d = 5;
1405
1406                 int? v2 = null;
1407                 Assert<int?> (d * v2, null, "#1");
1408                 Assert<int?> (d * null, null, "#1a");
1409                 Assert<int?> (null * d, null, "#1b");
1410
1411                 v2 = -2;
1412                 Assert (d * v2, -10, "#2");
1413                 dynamic d2 = (int?) -2;
1414                 Assert (d2 * 1, -2, "#2a");
1415
1416                 d = new MyType (5);
1417                 MyType? v3 = new MyType (30);
1418                 Assert (d * v3, new MyType (150), "#3");
1419                 dynamic d3 = new MyType? (new MyType (-7));
1420                 Assert (d3 * new MyType (6), new MyType (-42), "#3a");
1421                 Assert<MyType?> (d3 * null, null, "#3b");
1422
1423                 d = new MyTypeImplicitOnly (5);
1424                 decimal? v4 = 4m;
1425                 Assert (d * v4, 20m, "#4");
1426                 v4 = null;
1427                 Assert<decimal?> (d * v4, null, "#4a");
1428         }
1429
1430         void MultiplyCheckedTest ()
1431         {
1432                 checked {
1433                         dynamic d = 5;
1434
1435                         int v = int.MaxValue;
1436                         AssertChecked (() => d * v, 7, "#1");
1437
1438                         int? v2 = v;
1439                         AssertChecked (() => d * v2, null, "#2");
1440
1441                         d = new MyType (4);
1442                         MyType v3 = new MyType (int.MaxValue);
1443                         Assert (d * v3, new MyType (-4), "#3");
1444                 }
1445         }
1446
1447         void MultiplyAssignTest ()
1448         {
1449                 dynamic d = 5;
1450
1451                 int v = 2;
1452                 d *= v;
1453                 Assert (d, 10, "#1");
1454
1455                 d = 5.0;
1456                 double v2 = 0.5;
1457                 d *= v2;
1458                 Assert (d, 2.5, "#1a");
1459                 d *= v;
1460                 Assert (d, 5, "#1b");
1461
1462                 dynamic d3 = new MyType (-7);
1463                 d3 *= new MyType (6);
1464                 Assert<MyType> (d3, new MyType (-42), "#3");
1465
1466                 d = 5m;
1467                 decimal v4 = 4m;
1468                 d *= v4;
1469                 Assert (d, 20m, "#4");
1470                 
1471                 int i = 3;
1472                 d = 5;
1473                 i *= d;
1474                 Assert (i, 15, "#5");
1475         }
1476
1477         void MultiplyAssignCheckedTest ()
1478         {
1479                 checked {
1480                         dynamic d = 5;
1481
1482                         int v = int.MaxValue;
1483                         AssertChecked (() => { d *= v; Assert (d, 0, "#1-"); }, "#1");
1484
1485                         d = new MyType (44);
1486                         MyType v3 = new MyType (int.MaxValue);
1487                         d *= v3;
1488                         Assert (d, new MyType (-44), "#3-");
1489                 }
1490         }
1491
1492         void Negate ()
1493         {
1494                 dynamic d = -8;
1495                 Assert (8, -d, "#1");
1496                 Assert (-8, -(-d), "#1a");
1497
1498                 d = new MyType (-14);
1499                 Assert (new MyType (14), -d, "#2");
1500
1501                 d = new MyTypeImplicitOnly (4);
1502                 Assert (-4, -d, "#3");
1503
1504                 d = (uint) 7;
1505                 Assert (-7, -d, "#4");
1506
1507                 d = double.NegativeInfinity;
1508                 Assert (double.PositiveInfinity, -d, "#5");
1509         }
1510
1511         void NegateNullable ()
1512         {
1513                 dynamic d = (int?) -8;
1514                 Assert (8, -d, "#1");
1515                 Assert (-8, -(-d), "#1a");
1516
1517                 MyType? n1 = new MyType (4);
1518                 d = n1;
1519                 Assert (new MyType (-4), -d, "#2");
1520
1521                 MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
1522                 d = n2;
1523                 Assert (-4, -d, "#3");
1524
1525                 d = (sbyte?) 7;
1526                 Assert (-7, -d, "#4");
1527         }
1528
1529         void NegateChecked ()
1530         {
1531                 checked {
1532                         dynamic d = int.MinValue;
1533                         AssertChecked (() => -d, 0, "#1");
1534                 }
1535         }
1536
1537         void Not ()
1538         {
1539                 dynamic d = true;
1540                 Assert (false, !d, "#1");
1541
1542                 var de = new MyType (-1);
1543                 Assert (false, !d, "#2");
1544         }
1545
1546         void NotEqualTest ()
1547         {
1548                 dynamic d = 5;
1549
1550                 int v = 2;
1551                 Assert (d != v, true, "#1");
1552                 double v2 = 5;
1553                 Assert (d != v2, false, "#1a");
1554
1555                 d = true;
1556                 Assert (d != false, true, "#2");
1557                 bool b2 = true;
1558                 Assert (d != b2, false, "#2a");
1559
1560                 d = new MyType (30);
1561                 MyType v3 = new MyType (30);
1562                 Assert (d != v3, false, "#3");
1563                 dynamic d3 = new MyType (-7);
1564                 Assert (d3 != new MyType (6), true, "#3a");
1565
1566                 d = 2m;
1567                 decimal v4 = 4m;
1568                 Assert (d != v4, true, "#4");
1569                 Assert (d != 2m, false, "#4a");
1570
1571                 d = null;
1572                 Assert (d != null, false, "#5");
1573         }
1574
1575         void NotEqualNullableTest ()
1576         {
1577                 dynamic d = 5;
1578
1579                 int? v2 = null;
1580                 Assert (d != v2, true, "#1");
1581                 Assert (d != null, true, "#1a");
1582                 Assert (null != d, true, "#1b");
1583
1584                 v2 = -2;
1585                 Assert (d != v2, true, "#2");
1586                 dynamic d2 = (int?) -2;
1587                 Assert (d2 != 1, true, "#2a");
1588                 d2 = (uint?) 44;
1589                 Assert (d2 != 44, false, "#2b");
1590
1591                 d = new MyType (30);
1592                 MyType? v3 = new MyType (30);
1593                 Assert (d != v3, false, "#3");
1594                 dynamic d3 = new MyType? (new MyType (-7));
1595                 Assert (d3 != new MyType (6), true, "#3a");
1596                 Assert (d3 != null, true, "#3b");
1597
1598                 d = 4.1m;
1599                 decimal? v4 = 4m;
1600                 Assert (d != v4, true, "#4");
1601                 v4 = null;
1602                 Assert (d != v4, true, "#4a");
1603
1604                 d = (bool?) true;
1605                 Assert (d != true, false, "#5");
1606                 Assert (d != null, true, "#5a");
1607                 Assert (d != false, true, "#5b");
1608         }
1609
1610         void NotEqualEnumTest ()
1611         {
1612                 dynamic d = MyEnum.Value_1;
1613
1614                 Assert (d != null, true, "#1");
1615
1616                 Assert (d != MyEnum.Value_1, false, "#2");
1617                 Assert (d != 0, true, "#2a");
1618
1619                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1620                 Assert (d2 != MyEnumUlong.Value_2, false, "#3");
1621                 Assert (d2 != null, true, "#3a");
1622         }
1623
1624         void NotEqualStringTest ()
1625         {
1626                 dynamic d = "text";
1627
1628                 Assert (d != "te", true, "#1");
1629                 Assert (d != "text", false, "#1a");
1630                 Assert (d != null, true, "#1b");
1631         }
1632
1633         void OnesComplement ()
1634         {
1635                 dynamic d = 7;
1636                 Assert (-8, ~d, "#1");
1637
1638                 d = new MyType (-1);
1639                 Assert (0, ~d, "#2");
1640
1641                 d = (ulong) 7;
1642                 Assert (18446744073709551608, ~d, "#3");
1643
1644                 d = MyEnum.Value_1;
1645                 Assert ((MyEnum) 254, ~d, "#4");
1646         }
1647
1648         void OnesComplementNullable ()
1649         {
1650                 dynamic d = (int?) 7;
1651                 Assert (-8, ~d, "#1");
1652
1653                 d = (MyEnum?) MyEnum.Value_1;
1654                 Assert ((MyEnum) 254, ~d, "#4");
1655         }
1656
1657         void OrTest ()
1658         {
1659                 dynamic d = true;
1660
1661                 var v = false;
1662                 Assert (d | v, true, "#1");
1663                 Assert (d | false, true, "#1a");
1664
1665                 d = 42;
1666                 var v2 = 62;
1667                 Assert (d | v2, 62, "#2");
1668                 Assert (d | 0, 42, "#2a");
1669
1670                 d = new MyType (42);
1671                 MyType v3 = new MyType (30);
1672                 Assert (d | v3, new MyType (62), "#3");
1673                 dynamic d3 = new MyType (-7);
1674                 Assert<MyType> (d3 | new MyType (6), new MyType (-1), "#3a");
1675
1676                 d3 = new MyTypeImplicitOnly (-7);
1677                 Assert (d3 | 11, -5, "#3b");
1678         }
1679
1680         void OrTestEnum ()
1681         {
1682                 dynamic d = MyEnum.Value_1;
1683
1684                 Assert<MyEnum?> (d | null, null, "#1");
1685
1686                 Assert (d | d, MyEnum.Value_1, "#2");
1687
1688                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1689                 Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
1690         }
1691
1692         void OrTestNullable ()
1693         {
1694                 dynamic d = 5;
1695
1696                 int? v2 = null;
1697                 Assert<int?> (d | v2, null, "#1");
1698                 Assert<int?> (d | null, null, "#1a");
1699                 Assert<int?> (null | d, null, "#1b");
1700
1701                 v2 = -2;
1702                 Assert (d | v2, -1, "#2");
1703                 dynamic d2 = (int?) -2;
1704                 Assert (d2 | 1, -1, "#2a");
1705
1706                 d = new MyType (-2);
1707                 MyType? v3 = new MyType (30);
1708                 Assert (d | v3, new MyType (-2), "#3");
1709                 dynamic d3 = new MyType? (new MyType (-7));
1710                 Assert (d3 | new MyType (6), new MyType (-1), "#3a");
1711         }
1712
1713         void OrAssignedTest ()
1714         {
1715                 dynamic d = true;
1716
1717                 var v = false;
1718                 d |= v;
1719                 Assert (d, true, "#1");
1720                 d = true;
1721                 d |= true;
1722                 Assert (d, true, "#1a");
1723
1724                 d = 42;
1725                 var v2 = 62;
1726                 d |= v2;
1727                 Assert (d, 62, "#2");
1728
1729                 MyType v3 = new MyType (30);
1730                 dynamic d3 = new MyType (-7);
1731                 d3 |= new MyType (6);
1732                 Assert<MyType> (d3, new MyType (-1), "#3");
1733         }
1734
1735         void OrAssignedTestEnum ()
1736         {
1737                 dynamic d = MyEnum.Value_1;
1738                 d |= MyEnum.Value_2;
1739                 Assert<MyEnum> (d, (MyEnum) 3, "#1");
1740
1741                 d = MyEnum.Value_2;
1742                 d |= d;
1743                 Assert (d, MyEnum.Value_2, "#2");
1744
1745                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1746                 Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
1747         }
1748
1749         void OrElseTest ()
1750         {
1751                 dynamic d = true;
1752
1753                 var v = false;
1754                 Assert<bool> (d || v, true, "#1");
1755
1756                 Assert (d || true, true, "#1a");
1757
1758                 d = true;
1759                 Assert (d || d, true, "#2");
1760
1761                 dynamic d3 = new MyType (-7);
1762                 Assert<MyType> (d3 || new MyType (6), new MyType (-7), "#3");
1763         }
1764
1765         void RightShiftTest ()
1766         {
1767                 dynamic d = (ulong) 0x7F000;
1768
1769                 int v = 2;
1770                 Assert<ulong> (d >> v, 0x1FC00, "#1");
1771                 Assert<ulong> (d >> 1, 0x3F800, "#1a");
1772                 short s = 2;
1773                 Assert<ulong> (d >> s, 0x1FC00, "#1b");
1774
1775                 d = 0x7F000;
1776                 MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
1777                 Assert (d >> v3, 0xFE00, "#3");
1778                 dynamic d3 = new MyType (-7);
1779                 Assert (d3 >> new MyTypeImplicitOnly (11), -1, "#3a");
1780         }
1781
1782         void RightShiftNullableTest ()
1783         {
1784                 dynamic d = 5;
1785
1786                 int? v2 = null;
1787                 Assert<int?> (d >> v2, null, "#1");
1788                 d = 5;
1789                 Assert<int?> (d >> null, null, "#1a");
1790                 d = 5;
1791                 Assert<int?> (null >> d, null, "#1b");
1792
1793                 v2 = -2;
1794                 Assert (d >> v2, 0, "#2");
1795                 dynamic d2 = (int?) -200;
1796                 Assert (d2 >> 1, -100, "#2a");
1797         }
1798
1799         void RightShiftAssignTest ()
1800         {
1801                 dynamic d = 0x7F000;
1802
1803                 int v = 2;
1804                 d >>= v;
1805                 Assert (d, 0x1FC00, "#1");
1806                 d >>= 1;
1807                 Assert (d, 0xFE00, "#1a");
1808                 sbyte s = 2;
1809                 d >>= s;
1810                 Assert (d, 0x3F80, "#1b");
1811         }
1812
1813         void RightShiftAssignNullableTest ()
1814         {
1815                 dynamic d = 0x2A0;
1816
1817                 var v2 = -2;
1818                 d >>= v2;
1819                 Assert (d, 0, "#2");
1820                 dynamic d2 = (int?) -2;
1821                 d2 >>= 1;
1822                 Assert (d2, -1, "#2a");
1823         }
1824
1825         void SubtractTest ()
1826         {
1827                 dynamic d = 5;
1828
1829                 int v = 2;
1830                 Assert (d - v, 3, "#1");
1831                 double v2 = 0.5;
1832                 Assert (d - v2, 4.5, "#1a");
1833
1834                 d = new MyType (5);
1835                 MyType v3 = new MyType (30);
1836                 Assert (d - v3, new MyType (-25), "#3");
1837                 dynamic d3 = new MyType (-7);
1838                 Assert (d3 - new MyType (6), new MyType (-13), "#3a");
1839
1840                 d = new MyTypeImplicitOnly (5);
1841                 decimal v4 = 4m;
1842                 Assert (d - v4, 1m, "#4");
1843         }
1844
1845         void SubtractNullableTest ()
1846         {
1847                 dynamic d = 5;
1848
1849                 int? v2 = null;
1850                 Assert<int?> (d - v2, null, "#1");
1851                 Assert<int?> (d - null, null, "#1a");
1852                 Assert<int?> (null - d, null, "#1b");
1853
1854                 v2 = -2;
1855                 Assert (d - v2, 7, "#2");
1856                 dynamic d2 = (int?) -2;
1857                 Assert (d2 - 1, -3, "#2a");
1858
1859                 d = new MyType (5);
1860                 MyType? v3 = new MyType (30);
1861                 Assert (d - v3, new MyType (-25), "#3");
1862                 dynamic d3 = new MyType? (new MyType (-7));
1863                 Assert (d3 - new MyType (6), new MyType (-13), "#3a");
1864                 Assert<MyType?> (d3 - null, null, "#3b");
1865
1866                 d = new MyTypeImplicitOnly (5);
1867                 decimal? v4 = 4m;
1868                 Assert (d - v4, 1m, "#4");
1869                 v4 = null;
1870                 Assert<decimal?> (d - v4, null, "#4a");
1871         }
1872
1873         void SubtractEnumTest ()
1874         {
1875                 dynamic d = MyEnum.Value_1;
1876
1877                 Assert<MyEnum> (d - 1, 0, "#1");
1878
1879                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1880                 Assert (d2 - (byte) 1, MyEnumUlong.Value_1, "#2");
1881                 Assert<MyEnumUlong?> (d2 - null, null, "#2a");
1882                 
1883                 // CSC: Invalid System.InvalidOperationException
1884                 Assert<MyEnum?> (d - null, null, "#3");
1885         }
1886
1887         void SubtractCheckedTest ()
1888         {
1889                 checked {
1890                         dynamic d = 5;
1891
1892                         int v = int.MinValue;
1893                         AssertChecked (() => d - v, 7, "#1");
1894
1895                         int? v2 = v;
1896                         AssertChecked (() => d - v2, null, "#2");
1897
1898                         d = new MyType (5);
1899                         MyType v3 = new MyType (int.MinValue);
1900                         Assert (d - v3, new MyType (-2147483643), "#3");
1901                 }
1902         }
1903
1904         void SubtractAssignTest ()
1905         {
1906                 dynamic d = 5;
1907
1908                 int v = 2;
1909                 d -= v;
1910                 Assert (d, 3, "#1");
1911
1912                 d = 5.0;
1913                 double v2 = 0.5;
1914                 d -= v2;
1915                 Assert (d, 4.5, "#1a");
1916                 d -= v;
1917                 Assert (d, 2.5, "#1b");
1918
1919                 dynamic d3 = new MyType (-7);
1920                 d3 -= new MyType (6);
1921                 Assert<MyType> (d3, new MyType (-13), "#3");
1922
1923                 d = 5m;
1924                 decimal v4 = 4m;
1925                 d -= v4;
1926                 Assert (d, 1m, "#4");
1927         }
1928
1929         void SubtractAssignEnumTest ()
1930         {
1931                 dynamic d = MyEnum.Value_1;
1932
1933                 d -= 1;
1934                 Assert<MyEnum> (d, 0, "#2");
1935
1936                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1937                 d2 -= (byte) 1;
1938                 Assert (d2, MyEnumUlong.Value_1, "#3");
1939         }
1940
1941         void SubtractAssignCheckedTest ()
1942         {
1943                 checked {
1944                         dynamic d = 5;
1945
1946                         int v = int.MinValue;
1947                         AssertChecked (() => { d -= v; Assert (d, 0, "#1a"); }, "#1");
1948
1949                         d = new MyType (5);
1950                         MyType v3 = new MyType (int.MinValue);
1951                         d -= v3;
1952                         Assert (d, new MyType (-2147483643), "#3a");
1953                 }
1954         }
1955
1956         void SubtractAssignEvent ()
1957         {
1958                 Action print = () => { Console.WriteLine ("foo"); };
1959                 dynamic d = print;
1960                 
1961                 // FIXME: Will have to special case events
1962                 //ev_assign -= d;
1963                 //ev_assign ();
1964         }
1965
1966         void UnaryDecrement ()
1967         {
1968                 dynamic d = 3;
1969                 Assert (3, d--, "#1");
1970                 Assert (2, d, "#1a");
1971
1972                 d = 3;
1973                 Assert (2, --d, "#2");
1974                 Assert (2, d, "#2a");
1975
1976                 d = new MyType (-3);
1977                 Assert (new MyType (-3), d--, "#3");
1978                 Assert (new MyType (-1), d, "#3a");
1979         }
1980
1981         void UnaryDecrementCheckedTest ()
1982         {
1983                 checked {
1984                         dynamic d = int.MinValue;
1985
1986                         AssertChecked (() => { d--; Assert (d, -1073741824, "#1a"); }, "#1");
1987
1988                         d = new MyType (int.MinValue);
1989                         d--;
1990                         Assert (d, new MyType (-1073741824), "#2");
1991                 }
1992         }
1993
1994         void UnaryIncrement ()
1995         {
1996                 dynamic d = 3;
1997                 Assert (3, d++, "#1");
1998                 Assert (4, d, "#1a");
1999
2000                 d = 3;
2001                 Assert (4, ++d, "#2");
2002                 Assert (4, d, "#2a");
2003
2004                 d = new MyType (-3);
2005                 Assert (new MyType (-3), d++, "#3");
2006                 Assert (new MyType (-6), d, "#3a");
2007         }
2008
2009         void UnaryIncrementCheckedTest ()
2010         {
2011                 checked {
2012                         dynamic d = int.MaxValue;
2013
2014                         AssertChecked (() => { d++; Assert (d, 0, "#1a"); }, "#1");
2015
2016                         d = new MyType (int.MaxValue);
2017                         d++;
2018                         Assert (d, new MyType (-2), "#2");
2019                 }
2020         }
2021
2022         //void UnaryIsFalse ()
2023         //{
2024         //    dynamic d = this;
2025         //    object r = d == null;
2026         //    Assert (false, (bool) r, "#1");
2027         //    Assert<object> (true, d != null, "#1a");
2028         //}
2029
2030         void UnaryIsTrue ()
2031         {
2032                 dynamic d = true;
2033                 Assert (3, d ? 3 : 5, "#1");
2034
2035                 d = 4;
2036                 Assert (false, d < 1, "#2");
2037
2038                 d = new InverseLogicalOperator (true);
2039                 Assert (1, d ? 1 : -1, "#3");
2040         }
2041
2042         void UnaryPlus ()
2043         {
2044                 dynamic d = -8;
2045                 Assert (-8, +d, "#1");
2046                 Assert (-8, +(+d), "#1a");
2047
2048                 d = new MyType (14);
2049                 Assert (new MyType (334455), +d, "#2");
2050
2051                 d = new MyTypeImplicitOnly (4);
2052                 Assert (4, +d, "#3");
2053
2054                 d = (uint) 7;
2055                 Assert<uint> (7, +d, "#4");
2056         }
2057
2058         void UnaryPlusNullable ()
2059         {
2060                 dynamic d = (int?) -8;
2061                 Assert (-8, +d, "#1");
2062                 Assert (-8, +(+d), "#1a");
2063
2064                 MyType? n1 = new MyType (4);
2065                 d = n1;
2066                 Assert (new MyType (334455), +d, "#2");
2067
2068                 MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
2069                 d = n2;
2070                 Assert (4, +d, "#3");
2071
2072                 d = (sbyte?) 7;
2073                 Assert (7, +d, "#4");
2074         }
2075
2076 #pragma warning restore 169
2077
2078         static bool RunTest (MethodInfo test)
2079         {
2080                 Console.Write ("Running test {0, -25}", test.Name);
2081                 try {
2082                         test.Invoke (new Tester (), null);
2083                         Console.WriteLine ("OK");
2084                         return true;
2085                 } catch (Exception e) {
2086                         Console.WriteLine ("FAILED");
2087                         Console.WriteLine (e.ToString ());
2088                         return false;
2089                 }
2090         }
2091
2092         public static int Main ()
2093         {
2094                 var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
2095                                         where test.GetParameters ().Length == 0
2096                                         orderby test.Name
2097                                         select RunTest (test);
2098
2099                 int failures = tests.Count (a => !a);
2100                 Console.WriteLine (failures + " tests failed");
2101                 return failures;
2102         }
2103 }
2104