-// 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
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;
}
}
+ 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)
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;
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; }) +
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 (
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 ()
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 ()
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 ()
{
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 ()
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)];
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 ()
{
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);
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);