2010-06-17 Geoff Norton <gnorton@novell.com>
[mono.git] / mono / tests / generics-sharing.2.cs
blob6110cf2f8fad627ea0ccfb11c59fb75767efc348
1 using System;
2 using System.Collections.Generic;
3 using System.Reflection;
5 namespace GenericSharingTest {
7 public delegate int IntVoidDelegate ();
9 public class ClassA {}
10 public class ClassB {}
11 public class ClassC {}
13 public class GenExc<T> : Exception {}
15 public class NonGen {
16 public static int field = 123;
18 public static void doThrow () {
19 throw new GenExc<ClassA> ();
23 public class GenBi<S,T> {
24 public static int field = 123;
25 public static float floatField = 1.0f;
27 public static int staticMethod (int x) {
28 return x + field;
31 public static void staticVoidMethod (int x) {
32 field = x;
35 public static float staticFloatMethod () {
36 return floatField;
39 public static long staticLongMethod (long x) {
40 return x + field;
43 public static GenStruct<T> staticValueMethod (int x) {
44 return new GenStruct<T> (x);
48 public struct GenStruct<T> {
49 public static int staticField;
51 public int field;
52 public int dummy1;
53 public int dummy2;
54 public int dummy3;
56 public GenStruct (int f) {
57 field = f;
58 dummy1 = dummy2 = dummy3 = 0;
61 public int method (int x) {
62 return x + field;
66 public interface IGen<T> {
67 T[] iMethod ();
68 void voidIMethod (int x);
69 long longIMethod (long x);
70 float floatIMethod ();
71 GenStruct<T> valueIMethod (int x);
74 public class IGenImpl<T> : IGen<T> {
75 public int field;
77 public T[] iMethod () {
78 return new T[3];
81 public void voidIMethod (int x) {
82 field = x;
85 public long longIMethod (long x) {
86 return x + 1;
89 public float floatIMethod () {
90 return 1.0f;
93 public GenStruct<T> valueIMethod (int x) {
94 return new GenStruct<T> (x);
98 public class GenA<T> {
99 public static T[] arr;
101 static GenA () {
102 arr = new T [3];
105 public GenA () {}
107 public GenA<T> newGen () {
108 return new GenA<T> ();
111 public GenA<int> newGenInt () {
112 return new GenA<int> ();
115 public int getGenField () {
116 return GenB<ClassA>.field;
119 public int getNonGenField () {
120 return NonGen.field;
123 public int getGenStructStaticField () {
124 return GenStruct<T>.staticField;
127 public T[] getArr () {
128 return arr;
131 public T[] newArr () {
132 return new T [3];
135 public GenA<T>[] newSelfArr () {
136 return new GenA<T> [3];
139 public GenB<GenB<T>>[] newArrNested () {
141 GenB<GenB<T>>[] arr = null;
142 for (int i = 0; i < 10000000; ++i)
143 arr = new GenB<GenB<T>> [3];
145 return new GenB<GenB<T>> [3];
148 public int hash (T obj) {
149 return obj.GetHashCode ();
152 public T ident (T obj) {
153 return obj;
156 public T cast (Object obj) {
157 return (T)obj;
160 public GenStruct<T> structCast (Object obj) {
161 return (GenStruct<T>)obj;
164 public Type ldtokenT () {
165 return typeof (T);
168 public Type ldtokenIGenT () {
169 return typeof (IGen<T>);
172 public Type ldtokenGenAIGenT () {
173 return typeof (GenA<IGen<T>>);
176 public Type ldtokenGenB () {
177 return typeof (GenB<>);
180 public GenStruct<T>? makeNullable (Object obj) {
181 return (GenStruct<T>?)obj;
184 public object unmakeNullable (GenStruct<T>? obj) {
185 return (object)obj;
188 public void except () {
189 try {
190 NonGen.doThrow ();
192 catch (GenExc<T>) {
193 //Console.WriteLine("exception thrown");
197 public static void staticExcept () {
198 try {
199 NonGen.doThrow ();
201 catch (GenExc<T>) {
202 Console.WriteLine("exception thrown and caught");
206 public static int staticField = 54321;
208 public static int staticMethod () {
209 return staticField;
212 public static int staticMethodCaller () {
213 return staticMethod ();
216 public static float staticFloatField = 1.0f;
218 public static float staticFloatMethod () {
219 return staticFloatField;
222 public static int staticBiCaller (int x) {
223 return GenBi<int,T>.staticMethod (x);
226 public static void staticBiVoidCaller (int x) {
227 GenBi<int,T>.staticVoidMethod (x);
230 public static float staticBiFloatCaller () {
231 return GenBi<int,T>.staticFloatMethod ();
234 public static GenStruct<T> staticBiValueCaller (int x) {
235 return GenBi<int,T>.staticValueMethod (x);
238 public static int staticSharedBiCaller (int x) {
239 return GenBi<T,T>.staticMethod (x);
242 public static void staticSharedBiVoidCaller (int x) {
243 GenBi<T,T>.staticVoidMethod (x);
246 public static float staticSharedBiFloatCaller () {
247 return GenBi<T,T>.staticFloatMethod ();
250 public static GenStruct<T> staticSharedBiValueCaller (int x) {
251 return GenBi<T,T>.staticValueMethod (x);
254 public static long staticBiLongCaller (long x) {
255 return GenBi<int, T>.staticLongMethod (x);
258 public int structCaller (int x) {
259 GenStruct<GenA<T>> gs = new GenStruct<GenA<T>> (123);
261 return gs.method (x);
264 public T[] callInterface (IGen<T> ig) {
265 return ig.iMethod ();
268 public void callVoidInterface (IGen<T> ig, int x) {
269 ig.voidIMethod (x);
272 public long callLongInterface (IGen<T> ig, long x) {
273 return ig.longIMethod (x);
276 public float callFloatInterface (IGen<T> ig) {
277 return ig.floatIMethod ();
280 public GenStruct<T> callValueInterface (IGen<T> ig, int x) {
281 return ig.valueIMethod (x);
285 public class GenB<T> {
286 public static int field = 123;
289 public class GenC<T> {
290 public static int field ;
292 static GenC () {
293 field = 1234;
297 public class StaticTest<T> {
298 static int stat;
300 public StaticTest (int x) {
301 stat = x;
304 public int getStat () {
305 return stat;
308 public int getOtherStat () {
309 return StaticTest<Object>.stat;
312 public int getGenCStat () {
313 return GenC<T>.field;
317 public class GenADeriv<T> : GenA<T> {
318 public static int otherField = 123;
321 public class GenABDeriv<T> : GenA<GenB<T>> {
322 public T[] newDerivArr () {
323 return new T [3];
327 public class NonGenUser<T> where T : NonGen {
328 public int getNonGenField () {
329 return NonGen.field;
333 public class AccessTest<T> {
334 private static int field = 123;
336 public int getOtherField () {
337 return AccessTest<int>.field;
341 public class VirtualTest<T> {
342 public virtual T[] newArr () {
343 return new T [3];
347 public class VirtualTestDeriv<T> : VirtualTest<T> {
348 public override T[] newArr () {
349 return new T [4];
353 public class VirtualTestCaller<T> {
354 public T[] doCall (VirtualTest<T> vt) {
355 return vt.newArr ();
359 public class MyCons<T> {
360 public T car;
361 public MyCons<T> cdr;
363 public static void printCar (T _car) {
364 Console.WriteLine ("car " + _car.ToString () /* + " cdr " + _cdr.ToString () */);
367 public MyCons (T _car, MyCons<T> _cdr) {
368 //printCar (_car);
369 car = _car; cdr = _cdr;
372 public static MyCons<T> returnList (MyCons<T> l) { return l; }
374 public static MyCons<T> returnCdr (MyCons<T> cons) { return returnList(cons.cdr); }
377 public class MyPair<N,M> {
378 public N n;
379 public M m;
381 public MyPair (N _n, M _m) { n = _n; m = _m; }
384 public class MyDict<N,M> {
385 public MyPair<N,M> p;
387 public MyDict (N n, M m) { p = new MyPair<N,M> (n, m); }
390 public class RGCTXTest<T> {
391 public GenA<T>[] newAArr () {
392 return new GenA<T> [3];
396 public class RGCTXTestSubA<T> : RGCTXTest<T> {
397 public GenB<T>[] newBArr () {
398 return new GenB<T> [3];
402 public class RGCTXTestSubB<T> : RGCTXTest<T> {
403 public GenC<T>[] newCArr () {
404 return new GenC<T> [3];
408 public class RGCTXTestSubASub : RGCTXTestSubA<ClassA> {
411 public class RGCTXTestSubASubSub<T> : RGCTXTestSubASub {
412 public GenC<T>[] newCArr () {
413 return new GenC<T> [3];
417 public class main {
418 delegate void ActionDelegate ();
420 static bool haveError = false;
422 static void error (string message) {
423 haveError = true;
424 Console.WriteLine (message);
427 static void typeCheck (String method, Object obj, Type t) {
428 if (obj.GetType () != t)
429 error ("object from " + method + " should have type " + t.ToString () + " but has type " + obj.GetType ().ToString ());
432 static int callStaticMethod<T> () {
433 return GenA<T>.staticMethod ();
436 static void checkException<T> (String method, ActionDelegate action) where T : Exception {
437 try {
438 try {
439 action ();
440 } catch (T) {
441 return;
443 } catch (Exception exc) {
444 error ("method " + method + " should have thrown " + typeof (T).ToString () + " but did throw " + exc);
448 public static void work<T> (T obj, bool mustCatch) {
449 EqualityComparer<T> comp = EqualityComparer<T>.Default;
451 GenA<T> ga = new GenA<T> ();
453 typeCheck ("newGen", ga.newGen (), typeof (GenA<T>));
454 typeCheck ("newGenInt", ga.newGenInt (), typeof (GenA<int>));
455 typeCheck ("getArr", ga.getArr (), typeof (T[]));
456 typeCheck ("newArr", ga.newArr (), typeof (T[]));
457 typeCheck ("newSelfArr", ga.newSelfArr (), typeof (GenA<T>[]));
458 //ga.newArrNested ();
459 typeCheck ("newArrNested", ga.newArrNested (), typeof (GenB<GenB<T>>[]));
461 if (ga.getGenField () != 123)
462 error ("getGenField");
464 if (ga.getNonGenField () != 123)
465 error ("getNonGenField");
467 GenStruct<T>.staticField = 321;
468 if (ga.getGenStructStaticField () != 321)
469 error ("getGenStructStaticField");
470 GenStruct<T>.staticField = -1;
472 ga.hash (obj);
474 if (!comp.Equals (ga.ident (obj), obj))
475 error ("ident");
477 if (!comp.Equals (ga.cast (obj), obj))
478 error ("cast");
479 if (typeof (T).IsValueType) {
480 checkException<NullReferenceException> ("cast null value", delegate { ga.cast (null); });
481 } else {
482 if (ga.cast (null) != null)
483 error ("cast null");
486 GenStruct<T> genstructt = new GenStruct<T> (453);
487 if (ga.structCast ((object)genstructt).field != 453)
488 error ("structCast");
489 checkException<NullReferenceException> ("structCast null", delegate { ga.structCast (null); });
491 if (ga.makeNullable ((object)genstructt).Value.field != 453)
492 error ("makeNullable");
493 if (ga.makeNullable (null) != null)
494 error ("makeNullable null");
496 if (ga.ldtokenT () != typeof (T))
497 error ("ldtokenT");
498 if (ga.ldtokenIGenT () != typeof (IGen<T>))
499 error ("ldtokenIGenT");
500 if (ga.ldtokenGenAIGenT () != typeof (GenA<IGen<T>>))
501 error ("ldtokenGenAIGenT");
502 if (ga.ldtokenGenB () != typeof (GenB<>))
503 error ("ldtokenGenB");
505 if (callStaticMethod<T> () != 54321)
506 error ("staticMethod");
508 GenBi<int,T>.field = 123;
509 if (GenA<T>.staticBiCaller (123) != 246)
510 error ("staticBiCaller");
511 GenA<T>.staticBiVoidCaller (1234);
512 if (GenBi<int,T>.field != 1234)
513 error ("staticBiVoidCaller");
514 if (GenA<T>.staticBiFloatCaller () != 1.0f)
515 error ("staticBiFloatCaller");
516 if (GenA<T>.staticBiLongCaller (123) != 123 + 1234)
517 error ("staticBiLongCaller");
518 GenStruct<T> gs = GenA<T>.staticBiValueCaller (987);
519 if (gs.field != 987)
520 error ("staticBiValueCaller");
522 GenBi<T,T>.field = 123;
523 if (GenA<T>.staticSharedBiCaller (123) != 246)
524 error ("staticSharedBiCaller");
525 GenA<T>.staticSharedBiVoidCaller (1234);
526 if (GenBi<T,T>.field != 1234)
527 error ("staticSharedBiVoidCaller");
528 if (GenA<T>.staticSharedBiFloatCaller () != 1.0f)
529 error ("staticSharedBiFloatCaller");
530 GenStruct<T> gss = GenA<T>.staticSharedBiValueCaller (987);
531 if (gss.field != 987)
532 error ("staticSharedBiValueCaller");
534 IntVoidDelegate ivdel = new IntVoidDelegate (GenA<T>.staticMethod);
535 if (ivdel () != 54321)
536 error ("staticMethod delegate");
538 Type gatype = typeof (GenA<T>);
539 MethodInfo staticMethodInfo = gatype.GetMethod ("staticMethod");
540 if ((Convert.ToInt32 (staticMethodInfo.Invoke (null, null))) != 54321)
541 error ("staticMethod reflection");
543 if (GenA<T>.staticMethodCaller () != 54321)
544 error ("staticMethodCaller");
546 if (GenA<T>.staticFloatMethod () != 1.0)
547 error ("staticFloatMethod");
549 if (ga.structCaller (234) != 357)
550 error ("structCaller");
552 IGenImpl<T> igi = new IGenImpl<T> ();
554 typeCheck ("callInterface", ga.callInterface (igi), typeof (T[]));
555 if (ga.callLongInterface (igi, 345) != 346)
556 error ("callLongInterface");
557 GenStruct<T> gst = ga.callValueInterface (igi, 543);
558 if (gst.field != 543)
559 error ("callValueInterface");
560 ga.callVoidInterface (igi, 654);
561 if (igi.field != 654)
562 error ("callVoidInterface");
563 if (ga.callFloatInterface (igi) != 1.0f)
564 error ("callFloatInterface");
566 new GenADeriv<T> ();
568 if (mustCatch) {
569 checkException<GenExc<ClassA>> ("except", delegate { ga.except (); });
570 checkException<GenExc<ClassA>> ("staticExcept", delegate { GenA<T>.staticExcept (); });
571 } else {
572 ga.except ();
573 GenA<T>.staticExcept ();
576 MyDict<T, ClassB> dtb = new MyDict<T, ClassB> (obj, new ClassB ());
578 typeCheck ("MyPair", dtb.p, typeof (MyPair<T, ClassB>));
580 GenABDeriv<T> gabd = new GenABDeriv<T> ();
582 typeCheck ("GenABDeriv.newArr", gabd.newArr (), typeof (GenB<T>[]));
583 typeCheck ("GenABDeriv.newDerivArr", gabd.newDerivArr (), typeof (T[]));
585 RGCTXTest<T> rt = new RGCTXTest<T> ();
586 RGCTXTestSubA<T> rtsa = new RGCTXTestSubA<T> ();
587 RGCTXTestSubB<T> rtsb = new RGCTXTestSubB<T> ();
588 RGCTXTestSubASub rtsas = new RGCTXTestSubASub ();
589 RGCTXTestSubASubSub<T> rtsass = new RGCTXTestSubASubSub<T> ();
591 typeCheck ("rtsass.newCArr", rtsass.newCArr (), typeof (GenC<T>[]));
592 typeCheck ("rgsa.newBArr", rtsa.newBArr (), typeof (GenB<T>[]));
593 typeCheck ("rg.newAArr", rt.newAArr (), typeof (GenA<T>[]));
594 typeCheck ("rgsb.newCArr", rtsb.newCArr (), typeof (GenC<T>[]));
596 /* repeat all for each class */
597 typeCheck ("rtsass.newCArr", rtsass.newCArr (), typeof (GenC<T>[]));
598 typeCheck ("rtsass.newBArr", rtsass.newBArr (), typeof (GenB<ClassA>[]));
599 typeCheck ("rtsass.newAArr", rtsass.newAArr (), typeof (GenA<ClassA>[]));
601 typeCheck ("rtsas.newBArr", rtsas.newBArr (), typeof (GenB<ClassA>[]));
602 typeCheck ("rtsas.newAArr", rtsas.newAArr (), typeof (GenA<ClassA>[]));
604 typeCheck ("rtsa.newBArr", rtsa.newBArr (), typeof (GenB<T>[]));
605 typeCheck ("rtsa.newAArr", rtsa.newAArr (), typeof (GenA<T>[]));
607 typeCheck ("rtsb.newCArr", rtsb.newCArr (), typeof (GenC<T>[]));
608 typeCheck ("rtsb.newAArr", rtsb.newAArr (), typeof (GenA<T>[]));
610 typeCheck ("rt.newAArr", rt.newAArr (), typeof (GenA<T>[]));
613 public static void virtualTest<T> (VirtualTest<T> vt, int len) {
614 VirtualTestCaller<T> vtc = new VirtualTestCaller<T> ();
615 T[] arr = vtc.doCall (vt);
617 typeCheck ("virtualTest", arr, typeof (T[]));
619 if (arr.Length != len)
620 error ("virtualTest length");
623 public static void listTest () {
624 MyCons<string> ls = new MyCons<string> ("abc", null);
625 MyCons<string> cdr = MyCons<string>.returnCdr (ls);
627 if (cdr != null)
628 error ("cdr is not null");
631 public static int Main ()
633 work<ClassA> (new ClassA (), false);
634 work<ClassB> (new ClassB (), true);
635 work<ClassB> (new ClassB (), true);
636 work<ClassC> (new ClassC (), true);
637 work<GenA<ClassA>> (new GenA<ClassA> (), true);
638 work<int[]> (new int[3], true);
639 work<int> (123, true);
640 work<int?> (123, true);
641 work<GenStruct<ClassA>?> (new GenStruct<ClassA> (123), true);
642 work<GenStruct<ClassA>?> (null, true);
644 StaticTest<ClassA> sa = new StaticTest<ClassA> (1234);
645 StaticTest<ClassB> sb = new StaticTest<ClassB> (2345);
647 if (sa.getStat () != 1234)
648 error ("getStat");
649 if (sb.getStat () != 2345)
650 error ("getStat");
651 if (sa.getOtherStat () != 0)
652 error ("getOtherStat");
653 if (sa.getGenCStat () != 1234)
654 error ("getGenCStat A");
655 if (sb.getGenCStat () != 1234)
656 error ("getGenCStat B");
658 NonGenUser<NonGen> ngu = new NonGenUser<NonGen> ();
660 if (ngu.getNonGenField () != 123)
661 error ("getNonGenField");
663 AccessTest<ClassA> ata = new AccessTest<ClassA> ();
665 if (ata.getOtherField () != 123)
666 error ("getOtherField");
668 VirtualTest<ClassA> vta = new VirtualTest<ClassA> ();
669 VirtualTest<ClassB> vtb = new VirtualTestDeriv<ClassB> ();
671 virtualTest<ClassA> (vta, 3);
672 virtualTest<ClassB> (vtb, 4);
674 listTest ();
676 if (haveError)
677 return 1;
678 return 0;