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