New tests.
authorMarek Safar <marek.safar@gmail.com>
Thu, 19 May 2011 16:30:14 +0000 (17:30 +0100)
committerMarek Safar <marek.safar@gmail.com>
Thu, 19 May 2011 16:30:42 +0000 (17:30 +0100)
mcs/errors/cs1986-2.cs [new file with mode: 0644]
mcs/errors/cs1986-3.cs [new file with mode: 0644]
mcs/errors/cs1986.cs [new file with mode: 0644]
mcs/errors/cs1991.cs [new file with mode: 0644]
mcs/errors/cs1999-2.cs [new file with mode: 0644]
mcs/errors/cs1999.cs [new file with mode: 0644]
mcs/mcs/async.cs
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/ikvm.cs

diff --git a/mcs/errors/cs1986-2.cs b/mcs/errors/cs1986-2.cs
new file mode 100644 (file)
index 0000000..deb3aa9
--- /dev/null
@@ -0,0 +1,18 @@
+// CS1986: The `await' operand type `int' must have suitable GetAwaiter method
+// Line: 15
+// Compiler options: -langversion:future
+
+static class S
+{
+       public static void GetAwaiter (this int i)
+       {
+       }
+}
+
+class A
+{
+       static async void Test ()
+       {
+               await 1;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1986-3.cs b/mcs/errors/cs1986-3.cs
new file mode 100644 (file)
index 0000000..76beac7
--- /dev/null
@@ -0,0 +1,20 @@
+// CS1986: The `await' operand type `A' must have suitable GetAwaiter method
+// Line: 15
+// Compiler options: -langversion:future
+
+static class S
+{
+       public static void GetAwaiter (this int i)
+       {
+       }
+}
+
+class A
+{
+       bool GetAwaiter;
+       
+       static async void Test ()
+       {
+               await new A ();
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1986.cs b/mcs/errors/cs1986.cs
new file mode 100644 (file)
index 0000000..c1f3fea
--- /dev/null
@@ -0,0 +1,11 @@
+// CS1986: The `await' operand type `int' must have suitable GetAwaiter method
+// Line: 8
+// Compiler options: -langversion:future
+
+class A
+{
+       static async void Test ()
+       {
+               await 1;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1991.cs b/mcs/errors/cs1991.cs
new file mode 100644 (file)
index 0000000..e493b0c
--- /dev/null
@@ -0,0 +1,13 @@
+// CS1991: Cannot await `void' expression
+// Line: 10
+// Compiler options: -langversion:future
+
+using System;
+
+class A
+{
+       static async void Test ()
+       {
+               await Console.WriteLine ("await");
+       }
+}
diff --git a/mcs/errors/cs1999-2.cs b/mcs/errors/cs1999-2.cs
new file mode 100644 (file)
index 0000000..e84d5bd
--- /dev/null
@@ -0,0 +1,19 @@
+// CS1999: The awaiter type `int' must have suitable IsCompleted, OnCompleted, and GetResult members
+// Line: 16
+// Compiler options: -langversion:future
+
+static class S
+{
+       public static int GetAwaiter (this int i)
+       {
+               return 1;
+       }
+}
+
+class A
+{
+       static async void Test ()
+       {
+               await 9;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1999.cs b/mcs/errors/cs1999.cs
new file mode 100644 (file)
index 0000000..e84d5bd
--- /dev/null
@@ -0,0 +1,19 @@
+// CS1999: The awaiter type `int' must have suitable IsCompleted, OnCompleted, and GetResult members
+// Line: 16
+// Compiler options: -langversion:future
+
+static class S
+{
+       public static int GetAwaiter (this int i)
+       {
+               return 1;
+       }
+}
+
+class A
+{
+       static async void Test ()
+       {
+               await 9;
+       }
+}
\ No newline at end of file
index 740401ad102087491ed13cb06b885f96a36401ed..3f9081c414a6ed6a3a7ef1b1658b2c831b9f7f2d 100644 (file)
@@ -29,9 +29,12 @@ namespace Mono.CSharp
 
                        protected override void Error_TypeDoesNotContainDefinition (ResolveContext rc, TypeSpec type, string name)
                        {
-                               rc.Report.Error (1986, loc,
-                                       "The `await' operand type `{0}' must have suitable GetAwaiter method",
-                                       type.GetSignatureForError ());
+                               Error_WrongGetAwaiter (rc, loc, type);
+                       }
+
+                       protected override void Error_OperatorCannotBeApplied (ResolveContext rc, TypeSpec type)
+                       {
+                               rc.Report.Error (1991, loc, "Cannot await `{0}' expression", type.GetSignatureForError ());
                        }
                }
 
@@ -40,7 +43,7 @@ namespace Mono.CSharp
                MethodSpec on_completed;
 
                public Await (Expression expr, Location loc)
-                       : base (new AwaitableMemberAccess (expr), loc)
+                       : base (expr, loc)
                {
                }
 
@@ -80,6 +83,13 @@ namespace Mono.CSharp
                        mg_completed.EmitCall (ec, args);
                }
 
+               static void Error_WrongGetAwaiter (ResolveContext rc, Location loc, TypeSpec type)
+               {
+                       rc.Report.Error (1986, loc,
+                               "The `await' operand type `{0}' must have suitable GetAwaiter method",
+                               type.GetSignatureForError ());
+               }
+
                void Error_WrongAwaiterPattern (ResolveContext rc, TypeSpec awaiter)
                {
                        rc.Report.Error (1999, loc, "The awaiter type `{0}' must have suitable IsCompleted, OnCompleted, and GetResult members",
@@ -91,25 +101,30 @@ namespace Mono.CSharp
                        if (!base.Resolve (bc))
                                return false;
 
-                       //
-                       // Check whether the expression is awaitable
-                       //
-                       var t = expr.Type;
-
                        //
                        // The task t is of type dynamic
                        //
-                       if (t.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
+                       if (expr.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
                                throw new NotImplementedException ("dynamic await");
 
-                       var mg = expr as MethodGroupExpr;
-                       if (mg == null)
-                               throw new NotImplementedException ("wrong expression kind");
+                       //
+                       // Check whether the expression is awaitable
+                       //
+                       Expression ama = new AwaitableMemberAccess (expr).Resolve (bc);
+                       if (ama == null)
+                               return false;
 
                        Arguments args = new Arguments (0);
 
-                       //expr = mg.OverloadResolve (bc, ref args, null, OverloadResolver.Restrictions.NoBaseMembers);
-                       expr = new Invocation (expr, args).Resolve (bc);
+                       var errors_printer = new SessionReportPrinter ();
+                       var old = bc.Report.SetPrinter (errors_printer);
+                       ama = new Invocation (ama, args).Resolve (bc);
+
+                       if (errors_printer.ErrorsCount > 0 || !MemberAccess.IsValidDotExpression (ama.Type)) {
+                               bc.Report.SetPrinter (old);
+                               Error_WrongGetAwaiter (bc, loc, expr.Type);
+                               return false;
+                       }
 
                        var awaiter_type = expr.Type;
                        awaiter = ((AsyncTaskStorey) machine_initializer.Storey).AddAwaiter (awaiter_type, loc);
@@ -123,11 +138,18 @@ namespace Mono.CSharp
                                if (is_completed != null && is_completed.Type.BuiltinType == BuiltinTypeSpec.Type.Bool && is_completed.IsInstance && is_completed.Getter != null) {
                                        // valid
                                } else {
+                                       bc.Report.SetPrinter (old);
                                        Error_WrongAwaiterPattern (bc, awaiter_type);
                                        return false;
                                }
                        }
 
+                       if (errors_printer.ErrorsCount > 0) {
+                               bc.Report.SetPrinter (old);
+                               Error_WrongAwaiterPattern (bc, awaiter_type);
+                               return false;
+                       }
+
                        //
                        // void OnCompleted (Action)
                        //
index 1f12df3dbf823ebb6af2ee2225dc789b85a7b4bc..c8a8f044fc0401694c9458d458caf233fcf44329 100644 (file)
@@ -2509,7 +2509,6 @@ namespace Mono.CSharp {
                        get;
                }
 
-               // TODO: Not needed
                protected abstract TypeSpec DeclaringType {
                        get;
                }
index cdc977d083d45f3bc6768a463a27faf9f5460955..1d4471ee32b5ced1fcd7a62ccdbccf22a652c603 100644 (file)
@@ -7534,6 +7534,22 @@ namespace Mono.CSharp
                        return e;
                }
 
+               protected virtual void Error_OperatorCannotBeApplied (ResolveContext rc, TypeSpec type)
+               {
+                       if (type == InternalType.NullLiteral && rc.IsRuntimeBinder)
+                               rc.Report.Error (Report.RuntimeErrorId, loc, "Cannot perform member binding on `null' value");
+                       else
+                               Unary.Error_OperatorCannotBeApplied (rc, loc, ".", type);
+               }
+
+               public static bool IsValidDotExpression (TypeSpec type)
+               {
+                       const MemberKind dot_kinds = MemberKind.Class | MemberKind.Struct | MemberKind.Delegate | MemberKind.Enum |
+                               MemberKind.Interface | MemberKind.TypeParameter | MemberKind.ArrayType;
+
+                       return (type.Kind & dot_kinds) != 0;
+               }
+
                public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
                {
                        var sn = expr as SimpleName;
@@ -7594,14 +7610,8 @@ namespace Mono.CSharp
                                return new DynamicMemberBinder (Name, args, loc);
                        }
 
-                       const MemberKind dot_kinds = MemberKind.Class | MemberKind.Struct | MemberKind.Delegate | MemberKind.Enum |
-                               MemberKind.Interface | MemberKind.TypeParameter | MemberKind.ArrayType;
-
-                       if ((expr_type.Kind & dot_kinds) == 0) {
-                               if (expr_type == InternalType.NullLiteral && rc.IsRuntimeBinder)
-                                       rc.Report.Error (Report.RuntimeErrorId, loc, "Cannot perform member binding on `null' value");
-                               else
-                                       Unary.Error_OperatorCannotBeApplied (rc, loc, ".", expr_type);
+                       if (!IsValidDotExpression (expr_type)) {
+                               Error_OperatorCannotBeApplied (rc, expr_type);
                                return null;
                        }
 
@@ -8306,6 +8316,7 @@ namespace Mono.CSharp
                }
 
                #region Properties
+
                protected override TypeSpec DeclaringType {
                        get {
                                return best_candidate.DeclaringType;
index d78744d286cf860b1c45a3109b72c856c46abd61..28ea7758cd9a6ffd271f7281e4d3835378380798 100644 (file)
@@ -356,6 +356,9 @@ namespace Mono.CSharp
                                default_references.Add ("Microsoft.CSharp.dll");
                        }
 
+                       if (compiler.Settings.Version == LanguageVersion.Future)
+                               default_references.Add ("Mono.Async.dll");
+
                        return default_references.ToArray ();
                }