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

Generate async methods #70941

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ protected override bool IsAsyncSupportingFunctionSyntax(SyntaxNode node)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

view with whitespace off.

protected override bool IsAsyncReturnType(ITypeSymbol type, KnownTypes knownTypes)
=> IsIAsyncEnumerableOrEnumerator(type, knownTypes) ||
IsTaskLike(type, knownTypes);
knownTypes.IsTaskLike(type);

protected override SyntaxNode AddAsyncTokenAndFixReturnType(
bool keepVoid,
Expand Down Expand Up @@ -129,21 +129,21 @@ private static TypeSyntax FixMethodReturnType(
var returnType = methodSymbol.ReturnType;
if (IsIEnumerable(returnType, knownTypes) && IsIterator(methodSymbol, cancellationToken))
{
newReturnType = knownTypes.IAsyncEnumerableOfTTypeOpt is null
newReturnType = knownTypes.IAsyncEnumerableOfTType is null
? MakeGenericType(nameof(IAsyncEnumerable<int>), methodSymbol.ReturnType)
: knownTypes.IAsyncEnumerableOfTTypeOpt.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
: knownTypes.IAsyncEnumerableOfTType.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
}
else if (IsIEnumerator(returnType, knownTypes) && IsIterator(methodSymbol, cancellationToken))
{
newReturnType = knownTypes.IAsyncEnumeratorOfTTypeOpt is null
newReturnType = knownTypes.IAsyncEnumeratorOfTType is null
? MakeGenericType(nameof(IAsyncEnumerator<int>), methodSymbol.ReturnType)
: knownTypes.IAsyncEnumeratorOfTTypeOpt.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
: knownTypes.IAsyncEnumeratorOfTType.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
}
else if (IsIAsyncEnumerableOrEnumerator(returnType, knownTypes))
{
// Leave the return type alone
}
else if (!IsTaskLike(returnType, knownTypes))
else if (!knownTypes.IsTaskLike(returnType))
{
// If it's not already Task-like, then wrap the existing return type
// in Task<>.
Expand All @@ -167,8 +167,8 @@ private static bool IsIterator(IMethodSymbol method, CancellationToken cancellat
=> method.Locations.Any(static (loc, cancellationToken) => loc.FindNode(cancellationToken).ContainsYield(), cancellationToken);

private static bool IsIAsyncEnumerableOrEnumerator(ITypeSymbol returnType, KnownTypes knownTypes)
=> returnType.OriginalDefinition.Equals(knownTypes.IAsyncEnumerableOfTTypeOpt) ||
returnType.OriginalDefinition.Equals(knownTypes.IAsyncEnumeratorOfTTypeOpt);
=> returnType.OriginalDefinition.Equals(knownTypes.IAsyncEnumerableOfTType) ||
returnType.OriginalDefinition.Equals(knownTypes.IAsyncEnumeratorOfTType);

private static bool IsIEnumerable(ITypeSymbol returnType, KnownTypes knownTypes)
=> returnType.OriginalDefinition.Equals(knownTypes.IEnumerableOfTType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ private static TypeSyntax FixMethodReturnType(IMethodSymbol methodSymbol, TypeSy
// If the return type is Task<T>, then make the new return type "T".
newReturnType = returnType.GetTypeArguments()[0].GenerateTypeSyntax().WithTriviaFrom(returnTypeSyntax);
}
else if (returnType.OriginalDefinition.Equals(knownTypes.IAsyncEnumerableOfTTypeOpt) &&
else if (returnType.OriginalDefinition.Equals(knownTypes.IAsyncEnumerableOfTType) &&
knownTypes.IEnumerableOfTType != null)
{
// If the return type is IAsyncEnumerable<T>, then make the new return type IEnumerable<T>.
newReturnType = knownTypes.IEnumerableOfTType.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
}
else if (returnType.OriginalDefinition.Equals(knownTypes.IAsyncEnumeratorOfTTypeOpt) &&
else if (returnType.OriginalDefinition.Equals(knownTypes.IAsyncEnumeratorOfTType) &&
knownTypes.IEnumeratorOfTType != null)
{
// If the return type is IAsyncEnumerator<T>, then make the new return type IEnumerator<T>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,36 +197,5 @@ private async Task<Solution> AddAsyncTokenAsync(
var newDocument = document.WithSyntaxRoot(newRoot);
return newDocument.Project.Solution;
}

protected static bool IsTaskLike(ITypeSymbol returnType, KnownTypes knownTypes)
{
if (returnType.Equals(knownTypes.TaskType))
{
return true;
}

if (returnType.Equals(knownTypes.ValueTaskType))
{
return true;
}

if (returnType.OriginalDefinition.Equals(knownTypes.TaskOfTType))
{
return true;
}

if (returnType.OriginalDefinition.Equals(knownTypes.ValueTaskOfTTypeOpt))
{
return true;
}

if (returnType.IsErrorType())
{
return returnType.Name.Equals("Task") ||
returnType.Name.Equals("ValueTask");
}

return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ protected sealed override async Task FixAllAsync(
private static bool ShouldOfferFix(ITypeSymbol returnType, KnownTypes knownTypes)
=> IsTaskType(returnType, knownTypes)
|| returnType.OriginalDefinition.Equals(knownTypes.TaskOfTType)
|| returnType.OriginalDefinition.Equals(knownTypes.ValueTaskOfTTypeOpt);
|| returnType.OriginalDefinition.Equals(knownTypes.ValueTaskOfTType);

private static bool IsTaskType(ITypeSymbol returnType, KnownTypes knownTypes)
=> returnType.OriginalDefinition.Equals(knownTypes.TaskType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.MakeMethodAsynchronous
End Function

Protected Overrides Function IsAsyncReturnType(type As ITypeSymbol, knownTypes As KnownTypes) As Boolean
Return IsTaskLike(type, knownTypes)
Return knownTypes.IsTaskLike(type)
End Function

Protected Overrides Function AddAsyncTokenAndFixReturnType(
Expand Down Expand Up @@ -84,7 +84,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.MakeMethodAsynchronous
Dim functionStatement = node.SubOrFunctionStatement
Dim newFunctionStatement = AddAsyncKeyword(functionStatement)

If Not IsTaskLike(methodSymbol.ReturnType, knownTypes) Then
If Not knownTypes.IsTaskLike(methodSymbol.ReturnType) Then
' if the current return type is not already task-list, then wrap it in Task(of ...)
Dim returnType = knownTypes.TaskOfTType.Construct(methodSymbol.ReturnType).GenerateTypeSyntax().WithAdditionalAnnotations(Simplifier.AddImportsAnnotation)
newFunctionStatement = newFunctionStatement.WithAsClause(
Expand Down
18 changes: 12 additions & 6 deletions src/Features/CSharpTest/GenerateMethod/GenerateMethodTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8036,7 +8036,9 @@ private static int i()
""");
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/643")]
[Fact]
[WorkItem("https://github.com/dotnet/roslyn/issues/643")]
[WorkItem("https://github.com/dotnet/roslyn/issues/14467")]
public async Task TestGenerateMethodWithConfigureAwaitFalse()
{
await TestInRegularAndScriptAsync(
Expand Down Expand Up @@ -8067,15 +8069,17 @@ static void Main(string[] args)
bool x = await Goo().ConfigureAwait(false);
}

private static Task<bool> Goo()
private static async Task<bool> Goo()
{
throw new NotImplementedException();
}
}
""");
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/643")]
[Fact]
[WorkItem("https://github.com/dotnet/roslyn/issues/643")]
[WorkItem("https://github.com/dotnet/roslyn/issues/14467")]
public async Task TestGenerateMethodWithMethodChaining()
{
await TestInRegularAndScriptAsync(
Expand Down Expand Up @@ -8106,15 +8110,17 @@ static void Main(string[] args)
bool x = await Goo().ConfigureAwait(false);
}

private static Task<bool> Goo()
private static async Task<bool> Goo()
{
throw new NotImplementedException();
}
}
""");
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/643")]
[Fact]
[WorkItem("https://github.com/dotnet/roslyn/issues/643")]
[WorkItem("https://github.com/dotnet/roslyn/issues/14467")]
public async Task TestGenerateMethodWithMethodChaining2()
{
await TestInRegularAndScriptAsync(
Expand Down Expand Up @@ -8149,7 +8155,7 @@ static async void T()
});
}

private static Task<object> M()
private static async Task<object> M()
{
throw new NotImplementedException();
}
Expand Down
Loading
Loading