Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: GetAwaitExpressionInfo ignores BoundConversion #54296

Merged
merged 10 commits into from
Jun 24, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,85 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests
/// </summary>
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<int> task;
private TaskCompletionSource<int> source;

private TaskCompletionSource<int> Source
{
get
{
if (source == null)
{
source = new TaskCompletionSource<int>();
task = new ValueTask<int>(source.Task);
}
return source;
}
}
internal ValueTask<int> Task
{
get
{
_ = Source;
return task;
}
}

public void SetValue(int i)
{
Source.SetResult(i);
}
}

static class MyAwaitableExtension
{
public static System.Runtime.CompilerServices.ValueTaskAwaiter<int> 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<AwaitExpressionSyntax>().First();
bernd5 marked this conversation as resolved.
Show resolved Hide resolved
Assert.Equal("await x", awaitExpression.ToString());

var info = model.GetAwaitExpressionInfo(awaitExpression);
Assert.Equal(
"System.Runtime.CompilerServices.ValueTaskAwaiter<System.Int32> MyAwaitableExtension.GetAwaiter(this MyAwaitable a)",
info.GetAwaiterMethod.ToTestDisplayString()
);
Assert.Equal(
"System.Int32 System.Runtime.CompilerServices.ValueTaskAwaiter<System.Int32>.GetResult()",
info.GetResultMethod.ToTestDisplayString()
);
Assert.Equal(
"System.Boolean System.Runtime.CompilerServices.ValueTaskAwaiter<System.Int32>.IsCompleted { get; }",
info.IsCompletedProperty.ToTestDisplayString()
);
}

[Fact]
[WorkItem(711413, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/711413")]
public void TestAwaitInfo()
Expand Down