Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / tests / generics-sharing.2.cs
index 5f0118e25ddb43bd1085b92017fc4e05ca68d2d0..6110cf2f8fad627ea0ccfb11c59fb75767efc348 100644 (file)
@@ -46,6 +46,8 @@ public class GenBi<S,T> {
 }
 
 public struct GenStruct<T> {
+       public static int staticField;
+
        public int field;
        public int dummy1;
        public int dummy2;
@@ -69,10 +71,34 @@ public interface IGen<T> {
        GenStruct<T> valueIMethod (int x);
 }
 
+public class IGenImpl<T> : IGen<T> {
+       public int field;
+
+       public T[] iMethod () {
+               return new T[3];
+       }
+
+       public void voidIMethod (int x) {
+               field = x;
+       }
+
+       public long longIMethod (long x) {
+               return x + 1;
+       }
+
+       public float floatIMethod () {
+               return 1.0f;
+       }
+
+       public GenStruct<T> valueIMethod (int x) {
+               return new GenStruct<T> (x);
+       }
+}
+
 public class GenA<T> {
        public static T[] arr;
 
-       public static GenA () {
+       static GenA () {
                arr = new T [3];
        }
 
@@ -94,6 +120,10 @@ public class GenA<T> {
                return NonGen.field;
        }
 
+       public int getGenStructStaticField () {
+               return GenStruct<T>.staticField;
+       }
+
        public T[] getArr () {
                return arr;
        }
@@ -127,6 +157,10 @@ public class GenA<T> {
                return (T)obj;
        }
 
+       public GenStruct<T> structCast (Object obj) {
+               return (GenStruct<T>)obj;
+       }
+
        public Type ldtokenT () {
                return typeof (T);
        }
@@ -143,6 +177,14 @@ public class GenA<T> {
                return typeof (GenB<>);
        }
 
+       public GenStruct<T>? makeNullable (Object obj) {
+               return (GenStruct<T>?)obj;
+       }
+
+       public object unmakeNullable (GenStruct<T>? obj) {
+               return (object)obj;
+       }
+
        public void except () {
                try {
                        NonGen.doThrow ();
@@ -212,6 +254,32 @@ public class GenA<T> {
        public static long staticBiLongCaller (long x) {
                return GenBi<int, T>.staticLongMethod (x);
        }
+
+       public int structCaller (int x) {
+               GenStruct<GenA<T>> gs = new GenStruct<GenA<T>> (123);
+
+               return gs.method (x);
+       }
+
+       public T[] callInterface (IGen<T> ig) {
+               return ig.iMethod ();
+       }
+
+       public void callVoidInterface (IGen<T> ig, int x) {
+               ig.voidIMethod (x);
+       }
+
+       public long callLongInterface (IGen<T> ig, long x) {
+               return ig.longIMethod (x);
+       }
+
+       public float callFloatInterface (IGen<T> ig) {
+               return ig.floatIMethod ();
+       }
+
+       public GenStruct<T> callValueInterface (IGen<T> ig, int x) {
+               return ig.valueIMethod (x);
+       }
 }
 
 public class GenB<T> {
@@ -221,7 +289,7 @@ public class GenB<T> {
 public class GenC<T> {
        public static int field ;
 
-       public static GenC () {
+       static GenC () {
                field = 1234;
        }
 }
@@ -258,7 +326,7 @@ public class GenABDeriv<T> : GenA<GenB<T>> {
 
 public class NonGenUser<T> where T : NonGen {
        public int getNonGenField () {
-               return T.field;
+               return NonGen.field;
        }
 }
 
@@ -347,22 +415,36 @@ public class RGCTXTestSubASubSub<T> : RGCTXTestSubASub {
 }
 
 public class main {
+       delegate void ActionDelegate ();
+
        static bool haveError = false;
 
-       public static void error (string message) {
+       static void error (string message) {
                haveError = true;
                Console.WriteLine (message);
        }
 
-       public static void typeCheck (String method, Object obj, Type t) {
+       static void typeCheck (String method, Object obj, Type t) {
                if (obj.GetType () != t)
                        error ("object from " + method + " should have type " + t.ToString () + " but has type " + obj.GetType ().ToString ());
        }
 
-       public static int callStaticMethod<T> () {
+       static int callStaticMethod<T> () {
                return GenA<T>.staticMethod ();
        }
 
+       static void checkException<T> (String method, ActionDelegate action) where T : Exception {
+               try {
+                       try {
+                               action ();
+                       } catch (T) {
+                               return;
+                       }
+               } catch (Exception exc) {
+                       error ("method " + method + " should have thrown " + typeof (T).ToString () + " but did throw " + exc);
+               }
+       }
+
        public static void work<T> (T obj, bool mustCatch) {
                EqualityComparer<T> comp = EqualityComparer<T>.Default;
 
@@ -382,6 +464,11 @@ public class main {
                if (ga.getNonGenField () != 123)
                        error ("getNonGenField");
 
+               GenStruct<T>.staticField = 321;
+               if (ga.getGenStructStaticField () != 321)
+                       error ("getGenStructStaticField");
+               GenStruct<T>.staticField = -1;
+
                ga.hash (obj);
 
                if (!comp.Equals (ga.ident (obj), obj))
@@ -389,6 +476,22 @@ public class main {
 
                if (!comp.Equals (ga.cast (obj), obj))
                        error ("cast");
+               if (typeof (T).IsValueType) {
+                       checkException<NullReferenceException> ("cast null value", delegate { ga.cast (null); });
+               } else {
+                       if (ga.cast (null) != null)
+                               error ("cast null");
+               }
+
+               GenStruct<T> genstructt = new GenStruct<T> (453);
+               if (ga.structCast ((object)genstructt).field != 453)
+                       error ("structCast");
+               checkException<NullReferenceException> ("structCast null", delegate { ga.structCast (null); });
+
+               if (ga.makeNullable ((object)genstructt).Value.field != 453)
+                       error ("makeNullable");
+               if (ga.makeNullable (null) != null)
+                       error ("makeNullable null");
 
                if (ga.ldtokenT () != typeof (T))
                        error ("ldtokenT");
@@ -443,28 +546,28 @@ public class main {
                if (GenA<T>.staticFloatMethod () != 1.0)
                        error ("staticFloatMethod");
 
-               new GenADeriv<T> ();
+               if (ga.structCaller (234) != 357)
+                       error ("structCaller");
 
-               if (mustCatch) {
-                       bool didCatch = false;
+               IGenImpl<T> igi = new IGenImpl<T> ();
 
-                       try {
-                               ga.except ();
-                       } catch (GenExc<ClassA>) {
-                               didCatch = true;
-                       }
-                       if (!didCatch)
-                               error ("except");
+               typeCheck ("callInterface", ga.callInterface (igi), typeof (T[]));
+               if (ga.callLongInterface (igi, 345) != 346)
+                       error ("callLongInterface");
+               GenStruct<T> gst = ga.callValueInterface (igi, 543);
+               if (gst.field != 543)
+                       error ("callValueInterface");
+               ga.callVoidInterface (igi, 654);
+               if (igi.field != 654)
+                       error ("callVoidInterface");
+               if (ga.callFloatInterface (igi) != 1.0f)
+                       error ("callFloatInterface");
 
-                       didCatch = false;
+               new GenADeriv<T> ();
 
-                       try {
-                               GenA<T>.staticExcept ();
-                       } catch (GenExc<ClassA>) {
-                               didCatch = true;
-                       }
-                       if (!didCatch)
-                               error ("staticExcept");
+               if (mustCatch) {
+                       checkException<GenExc<ClassA>> ("except", delegate { ga.except (); });
+                       checkException<GenExc<ClassA>> ("staticExcept", delegate { GenA<T>.staticExcept (); });
                } else {
                        ga.except ();
                        GenA<T>.staticExcept ();
@@ -529,10 +632,14 @@ public class main {
        {
                work<ClassA> (new ClassA (), false);
                work<ClassB> (new ClassB (), true);
+               work<ClassB> (new ClassB (), true);
                work<ClassC> (new ClassC (), true);
                work<GenA<ClassA>> (new GenA<ClassA> (), true);
                work<int[]> (new int[3], true);
                work<int> (123, true);
+               work<int?> (123, true);
+               work<GenStruct<ClassA>?> (new GenStruct<ClassA> (123), true);
+               work<GenStruct<ClassA>?> (null, true);
 
                StaticTest<ClassA> sa = new StaticTest<ClassA> (1234);
                StaticTest<ClassB> sb = new StaticTest<ClassB> (2345);