Merge pull request #5560 from kumpera/wasm-work-p3
[mono.git] / mcs / tests / test-async-13.cs
index e8a6d1517a352755c05bccb35e92010ddf21233a..33279ff09595988f1308bea6f370a134fa8349b4 100644 (file)
@@ -1,19 +1,42 @@
-// Compiler options: -langversion:future
-
 using System;
 using System.Threading.Tasks;
 using System.Threading;
 using System.Reflection;
 using System.Linq;
+using System.Runtime.CompilerServices;
 
 struct S
 {
        public int Value;
+       public S2 s2;
+       
+       public S (int a1, string a2)
+       {
+               Value = a1;
+               s2 = new S2 ();
+       }
        
        public void SetValue (int value)
        {
                Value = value;
        }
+       
+       public static implicit operator S (Base b)
+       {
+               return new S (400, "a");
+       }
+       
+       public static S operator + (S a, S b)
+       {
+               return new S () {
+                       Value = a.Value + b.Value
+               };
+       }
+}
+
+struct S2
+{
+       public int Value;
 }
 
 enum E
@@ -23,12 +46,21 @@ enum E
 
 class Base
 {
-       protected int field_int;
+       public volatile int field_int;
        protected int field_this;
        protected int property_this_counter;
        
        public event Action Event;
        
+       public Base ()
+       {
+       }
+       
+       public Base (int arg, int arg2)
+       {
+               field_int = arg;
+       }
+       
        public bool PropertyBool {
                get {
                        return true;
@@ -60,6 +92,30 @@ class Base
                }
        }
        
+       public static bool operator true (Base a)
+       {
+               return true;
+       }
+
+       public static bool operator false (Base a)
+       {
+               return false;
+       }
+       
+       public static Base operator & (Base a, Base b)
+       {
+               return new Base () {
+                       field_int = 100
+               };
+       }
+       
+       public static Base operator | (Base a, Base b)
+       {
+               return new Base () {
+                       field_int = 200
+               };
+       }
+       
        protected int Call (int arg1, int arg2, int arg3)
        {
                if (arg1 != 5)
@@ -80,6 +136,25 @@ class Base
                return arg;
        }
        
+       public void CallBool (bool b)
+       {
+       }
+       
+       public int CallS (S s)
+       {
+               return s.Value;
+       }
+       
+       public T[] CreateArray<T> (int size)
+       {
+               return new T [size];
+       }
+       
+       protected static void CallRefParams (ref int i, params int[] i2)
+       {
+               i = 5;
+       }
+       
        protected int CallNamed (int a, int b)
        {
                return a - b;
@@ -93,12 +168,153 @@ class Base
 
 class Tester : Base
 {
+       async Task<bool> ArrayAccessTest_1 ()
+       {
+               bool[] b = new bool[1];
+               b [0] = await Task.Factory.StartNew (() => true);
+               return b[await Task.Factory.StartNew (() => 0)];
+       }
+       
+       async Task<int> ArrayAccessTest_2 ()
+       {
+               double[] b = new double[2];
+               b [await Task.Factory.StartNew (() => 1)] = 5.5;
+               if (b [1] != 5.5)
+                       return 1;
+               
+               var d = b [await Task.Factory.StartNew (() => 1)] = 2.5;
+               if (b [1] != 2.5)
+                       return 2;
+               
+               if (d != 2.5)
+                       return 3;
+               
+               d = b [await Task.Factory.StartNew (() => 1)] = await Task.Factory.StartNew (() => 4.4);
+               if (d != 4.4)
+                       return 4;
+               
+               return 0;
+       }
+
+       async Task<int> ArrayAccessTest_3 ()
+       {
+               decimal[] d = new decimal [4];
+               d[1] = 4;
+               
+               var r = ++d[await Task.Factory.StartNew (() => 1)];
+               if (r != 5)
+                       return 1;
+               
+               d [1] = 6;
+               d [await Task.Factory.StartNew (() => 1)] += await Task.Factory.StartNew (() => 9.9m);
+               if (d [1] != 15.9m)
+                       return 2;
+               
+               d [1] = 6;
+               r =  d [await Task.Factory.StartNew (() => 1)] -= await Task.Factory.StartNew (() => 5.9m);
+               if (d [1] != 0.1m)
+                       return 3;
+               
+               return 0;
+       }
+       
+       async Task<bool> ArrayAccessTest_4 ()
+       {
+               string[] s = new string [4];
+               s[1] = "a";
+               
+               s [await Task.Factory.StartNew (() => 1)] += await Task.Factory.StartNew (() => "b");
+               return s [1] == "ab";
+       }
+       
+       async Task<bool> ArrayAccessTest_5 ()
+       {
+               int[][] a = new int[3][];
+               a [1] = new int [5];
+               int index = 1;
+               CallRefParams (ref a[await Task.Factory.StartNew (() => index++)][0], await Task.Factory.StartNew (() => 3));
+               return a [1][0] == 5;
+       }
+
+       async Task<int> ArrayAccessTest_6 ()
+       {
+               int value = -6;
+               int[] a = new int[3] { 3, 6, 9 };
+               return a [await Task.Factory.StartNew (() => (long)1)] + value;
+       }
+       
+       async Task<bool> ArrayAccessTest_7 ()
+       {
+               short?[] s = new short?[] { 3, 2, 1 };
+               var r = s [await Task.Factory.StartNew (() => 1)]++;
+               return r == 2;
+       }
+
+       async Task<int> ArrayAccessTest_8 ()
+       {
+               var s = new byte?[] { 3, 2, 1 };
+               var r = s [await Task.Factory.StartNew (() => 1)] += await Task.Factory.StartNew (() => (byte)30);
+               if (r != 32)
+                       return 1;
+               
+               if (s [1] != 32)
+                       return 2;
+               
+               return 0;
+       }
+
+       async Task<int> ArrayAccessTest_9 ()
+       {
+               var s = new Base ();
+               s.CreateArray<int> (await Task.Factory.StartNew (() => 5)) [2] += 9;
+               s.CreateArray<int> (await Task.Factory.StartNew (() => 5)) [2] += await Task.Factory.StartNew (() => 9);
+               
+               var res = s.CreateArray<int> (await Task.Factory.StartNew (() => 5)) [2] += await Task.Factory.StartNew (() => 9);
+               if (res != 9)
+                       return 1;
+
+               s.CreateArray<S> (await Task.Factory.StartNew (() => 5)) [2] += await Task.Factory.StartNew (() => new S () { Value = 4 });
+               return 0;
+       }
+
+       async Task<bool> ArrayAccessTest_10 ()
+       {
+               var b = new bool [1] { true };
+               
+               var r = b [await Task.Factory.StartNew (() => 0)];
+               return r;
+       }
+
+       async Task<bool> ArrayAccessTest_11 ()
+       {
+               var a = new S [1];
+               a [await Task.Factory.StartNew (() => 0)].s2.Value += 5;
+               return a [await Task.Factory.StartNew(() => 0)].s2.Value == 5;
+       }
+
        async Task<int> AssignTest_1 ()
        {
                field_int = await Task.Factory.StartNew (() => 0);
                return field_int;
        }
        
+       async Task<bool> AssignTest_2 ()
+       {
+               long? l = await Task.Factory.StartNew<sbyte?> (() => null);
+               return l == null;
+       }
+       
+       async Task<int> AssignTest_3 ()
+       {
+               int a = await Task.Factory.StartNew (() => 1), b = await Task.Factory.StartNew (() => 2);
+               if (a != 1)
+                       return 1;
+               if (b != 2)
+                       return b;
+               
+               return 0;
+       }
+       
        async Task<int> BinaryTest_1 ()
        {
                return await Task.Factory.StartNew (() => { Thread.Sleep (10); return 5; }) +
@@ -116,6 +332,58 @@ class Tester : Base
                return b ? -1 : i == 8 ? 0 : i;
        }
        
+       async Task<int> BinaryTest_3 ()
+       {
+               var r = await Task.Factory.StartNew<bool?> (() => true) & await Task.Factory.StartNew<bool?> (() => null);
+               if (r != null)
+                       return 1;
+
+               r = await Task.Factory.StartNew<bool?> (() => null) | await Task.Factory.StartNew<bool?> (() => true);
+               if (r != true)
+                       return 2;
+               
+               r = await Task.Factory.StartNew<bool?> (() => null) != await Task.Factory.StartNew<bool?> (() => true);
+               if (r != true)
+                       return 3;
+
+               return 0;
+       }
+       
+       async Task<int> BinaryTest_4 ()
+       {
+               var r1 = await Task.Factory.StartNew<short?> (() => 2) * await Task.Factory.StartNew<byte?> (() => null);
+               if (r1 != null)
+                       return 1;
+
+               var r2 = await Task.Factory.StartNew<decimal?> (() => 100) / await Task.Factory.StartNew<decimal?> (() => null);
+               if (r2 != null)
+                       return 2;
+               
+               return 0;
+       }
+       
+       async Task<int> BinaryTest_5 ()
+       {
+               var r1 = await Task.FromResult (1) == 9;
+               if (r1)
+                       return 1;
+               
+               var r2 = 1 == await Task.FromResult (1);
+               if (!r2)
+                       return 2;
+               
+               return 0;
+       }
+
+       async Task<bool> BinaryTest_6 ()
+       {
+               var t = Task.Delay (1);
+               if (t == await Task.WhenAny(new [] { t }))
+                       return true;
+
+               return false;
+       }
+
        async Task<int> CallTest_1 ()
        {
                return Call (
@@ -143,7 +411,7 @@ class Tester : Base
 
        async Task<bool> CallTest_4 ()
        {
-               return E.E_1.Equals (await Task.Factory.StartNew (() => E.E_1));
+               return E.E_1.Equals (unchecked (await Task.Factory.StartNew (() => E.E_1)));
        }
 
        async Task<int> CallTest_5 ()
@@ -153,13 +421,34 @@ class Tester : Base
                        b: await Task.Factory.StartNew (() => value++),
                        a: value) - 1;
        }
-
+       
+       async Task<bool> CastTest_1 ()
+       {
+               decimal value = 67;
+               return (value - await Task.Factory.StartNew (() => 66m)) == 1;
+       }
+       
+       async Task<bool> CastTest_2 ()
+       {
+               var t = new Tester ();
+               return t.CallS (await Task.Factory.StartNew (() => this)) == 400;
+       }
+       
+       async Task<bool> CoalescingTest_1 ()
+       {
+               var r = await Task.Factory.StartNew<string> (() => null)  ?? await Task.Factory.StartNew (() => "x");
+               return r == "x";
+       }
+       
+       async Task<bool> CoalescingTest_2 ()
+       {
+               var r = await Task.Factory.StartNew<short?> (() => null)  ?? await Task.Factory.StartNew<byte> (() => 2);
+               return r == 2;
+       }
+       
        async Task<int> ConditionalTest_1 ()
        {
-               // TODO: problem with Resumable point setup when the expression never emitted
-               //bool b = true;
-               //return true ? await Task.Factory.StartNew (() => 0) : await Task.Factory.StartNew (() => 1);
-               return 0;
+               return true ? await Task.Factory.StartNew (() => 0) : await Task.Factory.StartNew (() => 1);
        }
        
        async Task<int> ConditionalTest_2 ()
@@ -197,6 +486,23 @@ class Tester : Base
                CallEvent ();
                return value - 5;
        }
+       
+       async Task<int> FieldTest_1 ()
+       {
+               var s = new Base ();
+               s.field_int = 3;
+               s.field_int += await Task.Factory.StartNew (() => 6);
+               if (s.field_int != 9)
+                       return 1;
+               
+               var r = s.field_int -= await Task.Factory.StartNew (() => 5);
+               if (r != 4)
+                       return 2;
+               
+               if (s.field_int != 4)
+                       return 3;
+               return 0;
+       }
 
        async Task<bool> IndexerTest_1 ()
        {
@@ -212,9 +518,9 @@ class Tester : Base
        
        async Task<int> IndexerTest_3 ()
        {
-               int value = 3;
+               int value = -5;
                this[await Task.Factory.StartNew (() => value++)] += await Task.Factory.StartNew (() => 5);
-               return this[3] - 15;
+               return this[3] + 25;
        }
        
        async Task<int> IndexerTest_4 ()
@@ -235,9 +541,137 @@ class Tester : Base
                if (PropertyThis[0] != 27)
                        return 2;
 
+               return PropertyThis[5] -= await Task.Factory.StartNew (() => 27);
+       }
+       
+       async Task<int> IndexerTest_6 ()
+       {
+               var r = this[3] = await Task.Factory.StartNew (() => 9);
+               if (r != 9)
+                       return 1;
+               
+               var r2 = this[await Task.Factory.StartNew (() => 55)] = await Task.Factory.StartNew (() => 8);
+
+               if (r2 != 8)
+                       return 2;
+               
                return 0;
        }
        
+       async Task<bool> IndexerTest_7 ()
+       {
+               int value = -5;
+               var res = ++this[await Task.Factory.StartNew (() => value++)];
+               return res == 1;
+       }
+       
+       async Task<bool> IsTest_1 ()
+       {
+               new Tester ().CallBool (await Task.Factory.StartNew (() => new Tester ()) is Base);
+               return true;
+       }
+
+       async Task<bool> IsTest_2 ()
+       {
+               var r = await Task.Factory.StartNew<uint?> (() => 1) is uint;
+               return r;
+       }
+       
+       async Task<bool> LogicalUserOperator_1 ()
+       {
+               var r = await Task.Factory.StartNew (() => new Base ()) && await Task.Factory.StartNew (() => new Base ());
+               return r.field_int == 100;
+       }
+       
+       async Task<bool> LogicalUserOperator_2 ()
+       {
+               var r = new Base () && await Task.Factory.StartNew (() => new Base ());
+               return r.field_int == 100;
+       }
+       
+       async Task<bool> LogicalUserOperator_3 ()
+       {
+               var r = await Task.Factory.StartNew (() => new Base ()) || await Task.Factory.StartNew (() => new Base ());
+               return r.field_int == 0;
+       }
+
+       async Task<bool> NewTest_1 ()
+       {
+               int value = 9;
+               var b = new Base (value, await Task.Factory.StartNew (() => 33));
+               return b.field_int == 9;
+       }
+       
+       async Task<bool> NewTest_2 ()
+       {
+               var s = new S (await Task.Factory.StartNew (() => 77), await Task.Factory.StartNew (() => "b"));
+               return s.Value == 77;
+       }
+
+       async Task<int> NewDelegate_1 ()
+       {
+               var f = new Func<int> (await NewDelegate_1_0 ());
+               return f ();
+       }
+
+       static async Task<Func<int>> NewDelegate_1_0 ()
+       {
+               await Task.Factory.StartNew (() => { });
+               return () => 0;         
+       }
+       
+       async Task<int> NewInitTest_1 ()
+       {
+               int value = 9;
+               
+               var b = new Base (value, await Task.Factory.StartNew (() => 33)) { };
+               if (b.field_int != 9)
+                       return 1;
+               
+               b = new Base (value, await Task.Factory.StartNew (() => 11)) {
+                       field_int = await Task.Factory.StartNew (() => 12),
+                       PropertyInt = await Task.Factory.StartNew (() => 13)
+               };
+               
+               if (b.field_int != 25)
+                       return 2;
+               
+               b = new Base () {
+                       field_int = await Task.Factory.StartNew (() => 12),
+                       PropertyInt = await Task.Factory.StartNew (() => 13)
+               };
+
+               if (b.field_int != 25)
+                       return 3;
+               
+               return 0;
+       }
+       
+       async Task<int> NewInitTest_2 ()
+       {
+               int value = 9;
+               
+               var s = new S (value, await Task.Factory.StartNew (() => "x")) { };
+               if (s.Value != 9)
+                       return 1;
+               
+               s = new S (value, await Task.Factory.StartNew (() => "y")) {
+                       Value = await Task.Factory.StartNew (() => 12)
+               };
+
+               if (s.Value != 12)
+                       return 2;
+               
+               s = new S () {
+                       Value = await Task.Factory.StartNew (() => 13)
+               };
+               
+               if (s.Value != 13)
+                       return 3;
+               
+               return 0;
+       }
+
        async Task<bool> NewArrayInitTest_1 ()
        {
                var a = new int[await Task.Factory.StartNew (() => 5)];
@@ -271,6 +705,18 @@ class Tester : Base
                var a = new S[] { await Task.Factory.StartNew (() => new S () { Value = 4 }) };
                return a [0].Value - 4;
        }
+       
+       async Task<bool> NewArrayInitTest_6 ()
+       {
+               var a = new int[] { 2, 3, 2, 3, 5, 6, 7, 2, 4, await Task.Factory.StartNew (() => 5), 11, 23, 45 };
+               return a.Length == 13;
+       }
+       
+       async Task<bool> NewArrayInitTest_7 ()
+       {
+               var res = new [] { "a", new [] { "1", await Task.FromResult ("2") } [1], "b" };
+               return res [1] == "2";
+       }
 
        async Task<bool> PropertyTest_1 ()
        {
@@ -287,13 +733,58 @@ class Tester : Base
                return PropertyInt - 6;
        }
        
+       async Task<int> PropertyTest_3 ()
+       {
+               var r = PropertyThis.PropertyInt = await Task.Factory.StartNew (() => 9);
+               if (r != 9)
+                       return 1;
+               
+               PropertyThis.PropertyInt = 4;
+               int[] a = new int[4];
+               a [await Task.Factory.StartNew (() => 1)] = PropertyThis.PropertyInt += await Task.Factory.StartNew (() => 8);
+               if (a[1] != 21)
+                       return 2;
+               
+               if (PropertyThis.PropertyInt != 34)
+                       return 3;
+               
+               return 0;
+       }
+       
        async Task<bool> StringConcatTest_1 ()
        {
                return (await Task.Factory.StartNew (() => "a") +
                        await Task.Factory.StartNew (() => "b") +
                        await Task.Factory.StartNew (() => (string) null) == "ab");
        }
+
+       async Task<bool> UnaryTest_1 ()
+       {
+               long a = 1;
+               return (a + checked (-await Task.Factory.StartNew (() => 2))) == -1;
+       }
+
+       async Task<bool> UnaryTest_2 ()
+       {
+               short? s = 2;
+               int value = 2;
+               return (value * ~await Task.Factory.StartNew (() => s)) == -6;
+       }
+
+       async Task<bool> UnaryTest_3 ()
+       {
+               var d = new decimal? [2];
+               d[1] = 4;
+               var r = ++d[await Task.Factory.StartNew (() => 1)];
+               return r == 5;
+       }
        
+       async Task<bool> VariableInitializer_1 ()
+       {
+               int a = 2, b = await Task.Factory.StartNew (() => 1), c = await Task.Factory.StartNew (() => 1);
+               return a == (b + c);
+       }
+
        static bool RunTest (MethodInfo test)
        {
                Console.Write ("Running test {0, -25}", test.Name);
@@ -332,7 +823,7 @@ class Tester : Base
        public static int Main ()
        {
                var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
-                                       where test.GetParameters ().Length == 0
+                                       where test.GetParameters ().Length == 0 && !test.IsDefined (typeof (CompilerGeneratedAttribute), false)
                                        orderby test.Name
                                        select RunTest (test);