From 9193177d59a72a4cb4ecc402f3258fdf688673e1 Mon Sep 17 00:00:00 2001 From: Bernd Baumanns Date: Thu, 24 Jun 2021 20:02:16 +0200 Subject: [PATCH] Bugfix: GetAwaitExpressionInfo ignores BoundConversion (#54296) fixes #54298 Bugfix to handle "BoundConversion" --- .../Compilation/MemberSemanticModel.cs | 2 +- .../Semantics/AwaitExpressionTests.cs | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs index 85c6f95ffd137..a106610962e31 100644 --- a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs @@ -899,7 +899,7 @@ public override AwaitExpressionInfo GetAwaitExpressionInfo(AwaitExpressionSyntax throw new ArgumentException("node.Kind==" + node.Kind()); } - var bound = GetUpperBoundNode(node); + var bound = GetLowerBoundNode(node); BoundAwaitableInfo awaitableInfo = (((bound as BoundExpressionStatement)?.Expression ?? bound) as BoundAwaitExpression)?.AwaitableInfo; if (awaitableInfo == null) { diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs index ff547024e3d84..dd27e4aff990f 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs @@ -20,6 +20,85 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests /// public class AwaitExpressionTests : CompilingTestBase { + [Fact] + public void TestAwaitInfoExtensionMethod() + { + var text = +@"using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +static class App{ + public static async Task Main(){ + var x = new MyAwaitable(); + x.SetValue(42); + + Console.WriteLine(await x + ""!""); + } +} + +struct MyAwaitable +{ + private ValueTask task; + private TaskCompletionSource source; + + private TaskCompletionSource Source + { + get + { + if (source == null) + { + source = new TaskCompletionSource(); + task = new ValueTask(source.Task); + } + return source; + } + } + internal ValueTask Task + { + get + { + _ = Source; + return task; + } + } + + public void SetValue(int i) + { + Source.SetResult(i); + } +} + +static class MyAwaitableExtension +{ + public static System.Runtime.CompilerServices.ValueTaskAwaiter GetAwaiter(this MyAwaitable a) + { + return a.Task.GetAwaiter(); + } +}"; + + var csCompilation = CreateCompilation(text, targetFramework: TargetFramework.NetCoreAppAndCSharp); + var tree = csCompilation.SyntaxTrees.Single(); + + var model = csCompilation.GetSemanticModel(tree); + var awaitExpression = tree.GetRoot().DescendantNodes().OfType().First(); + Assert.Equal("await x", awaitExpression.ToString()); + + var info = model.GetAwaitExpressionInfo(awaitExpression); + Assert.Equal( + "System.Runtime.CompilerServices.ValueTaskAwaiter MyAwaitableExtension.GetAwaiter(this MyAwaitable a)", + info.GetAwaiterMethod.ToTestDisplayString() + ); + Assert.Equal( + "System.Int32 System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()", + info.GetResultMethod.ToTestDisplayString() + ); + Assert.Equal( + "System.Boolean System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted { get; }", + info.IsCompletedProperty.ToTestDisplayString() + ); + } + [Fact] [WorkItem(711413, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/711413")] public void TestAwaitInfo()