-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Add async modifier on await completion #48352
Merged
Merged
Changes from all commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
f1df660
Add async modifier on await completion
Youssef1313 60f8850
Localize and sealed
Youssef1313 447f01f
Fixes
Youssef1313 5938d3d
Use GetRequiredSemanticModelAsync instead
Youssef1313 73f43bb
Update CompletionProviderOrderTests.cs
Youssef1313 854945e
Merge branch 'main' into await-completion
Youssef1313 994932f
Make single completion provider for await
Youssef1313 1902c94
Tests
Youssef1313 39a17aa
Remove #nullable disable
Youssef1313 a39c348
Tests and not use field in completion provider
Youssef1313 50ca76e
Introduce a language service to share common code
Youssef1313 36b1ac8
Comments
Youssef1313 a5eeb67
Clean tests
Youssef1313 0431d4a
Fix NRE
Youssef1313 71cce7f
Fix
Youssef1313 c4aa2bb
Address feedback
Youssef1313 8cfc8f9
Test glyph and inline description in unit tests
Youssef1313 45a9f6b
Support anonymous functions
Youssef1313 77bf329
Fix
Youssef1313 0caf239
Rename test class
Youssef1313 61a0823
Fix failing test
Youssef1313 2f68771
Fix TestCompletionProviderOrderMetadata
Youssef1313 408eed7
Move to KnownTaskTypes
Youssef1313 60b0f5a
Merge branch 'main' into await-completion
Youssef1313 6a8534e
Merge branch 'main' into await-completion
Youssef1313 bf2ccad
Fix
Youssef1313 4626e1c
Merge remote-tracking branch 'upstream/main' into await-completion
Youssef1313 b581185
Address feedback: override the public overload
Youssef1313 2f921c3
Add async regardless return type
Youssef1313 a4b7a01
Update VisualBasicMakeMethodSynchronousCodeFixProvider.vb
Youssef1313 cf21c76
Update VisualBasicMakeMethodAsynchronousCodeFixProvider.vb
Youssef1313 f82655c
Fix
Youssef1313 6324aba
Fix test
Youssef1313 d501fee
Fix tests
Youssef1313 9204341
Fix test
Youssef1313 d48175c
Merge remote-tracking branch 'upstream/main' into await-completion
Youssef1313 c5f219a
Handle trivia
Youssef1313 de41203
Fix
Youssef1313 f4bcff7
Fix
Youssef1313 7546e52
Fix
Youssef1313 ee6d1cc
Merge branch 'main' into await-completion
Youssef1313 2e2f041
Address feedback
Youssef1313 d259bc9
Merge remote-tracking branch 'upstream/main' into await-completion
Youssef1313 a376f7c
Handle explicit lambda return type
Youssef1313 8f85b57
Fix tests
Youssef1313 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
283 changes: 283 additions & 0 deletions
283
src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AwaitCompletionProviderTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,283 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Completion.Providers; | ||
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionProviders; | ||
using Microsoft.CodeAnalysis.Test.Utilities; | ||
using Roslyn.Test.Utilities; | ||
using Xunit; | ||
|
||
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Recommendations | ||
{ | ||
/// <summary> | ||
/// The <see cref="AwaitCompletionProvider"/> adds async modifier if the return type is Task or ValueTask. | ||
/// The tests here are only checking whether the completion item is provided or not. | ||
/// Tests for checking adding async modifier are in: | ||
/// src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests_AwaitCompletion.vb | ||
/// </summary> | ||
[Trait(Traits.Feature, Traits.Features.Completion)] | ||
public class AwaitCompletionProviderTests : AbstractCSharpCompletionProviderTests | ||
{ | ||
internal override Type GetCompletionProviderType() => typeof(AwaitCompletionProvider); | ||
|
||
private async Task VerifyAbsenceAsync(string code) | ||
{ | ||
await VerifyItemIsAbsentAsync(code, "await"); | ||
} | ||
|
||
private async Task VerifyAbsenceAsync(string code, LanguageVersion languageVersion) | ||
{ | ||
await VerifyItemIsAbsentAsync(GetMarkup(code, languageVersion), "await"); | ||
} | ||
|
||
private async Task VerifyKeywordAsync(string code, LanguageVersion languageVersion, string? inlineDescription = null) | ||
{ | ||
await VerifyItemExistsAsync(GetMarkup(code, languageVersion), "await", glyph: (int)Glyph.Keyword, inlineDescription: inlineDescription); | ||
} | ||
|
||
[Fact] | ||
public async Task TestNotInTypeContext() | ||
{ | ||
await VerifyAbsenceAsync(@" | ||
class Program | ||
{ | ||
$$ | ||
}"); | ||
} | ||
|
||
[Fact] | ||
public async Task TestStatementInMethod() | ||
{ | ||
await VerifyKeywordAsync(@" | ||
class C | ||
{ | ||
void F() | ||
{ | ||
$$ } | ||
}", LanguageVersion.CSharp9, CSharpFeaturesResources.Make_container_async); | ||
} | ||
|
||
[Fact] | ||
public async Task TestStatementInMethod_Async() | ||
{ | ||
await VerifyKeywordAsync(@" | ||
class C | ||
{ | ||
async Task F() | ||
{ | ||
$$ } | ||
}", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestStatementInMethod_TopLevel() | ||
{ | ||
await VerifyKeywordAsync("$$", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestExpressionInAsyncMethod() | ||
{ | ||
await VerifyKeywordAsync(@" | ||
class C | ||
{ | ||
async Task F() | ||
{ | ||
var z = $$ } | ||
} | ||
", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestExpressionInNonAsyncMethodWithTaskReturn() | ||
{ | ||
await VerifyKeywordAsync(@" | ||
class C | ||
{ | ||
Task F() | ||
{ | ||
var z = $$ } | ||
} | ||
", LanguageVersion.CSharp9, CSharpFeaturesResources.Make_container_async); | ||
} | ||
|
||
[Fact] | ||
public async Task TestExpressionInAsyncMethod_TopLevel() | ||
{ | ||
await VerifyKeywordAsync("var z = $$", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestUsingStatement() | ||
{ | ||
await VerifyAbsenceAsync(@" | ||
class C | ||
{ | ||
async Task F() | ||
{ | ||
using $$ } | ||
}", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestUsingStatement_TopLevel() | ||
{ | ||
await VerifyAbsenceAsync("using $$", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestUsingDirective() | ||
=> await VerifyAbsenceAsync("using $$"); | ||
|
||
[Fact] | ||
public async Task TestGlobalUsingDirective() | ||
=> await VerifyAbsenceAsync("global using $$"); | ||
|
||
[Fact] | ||
public async Task TestForeachStatement() | ||
{ | ||
await VerifyAbsenceAsync(@" | ||
class C | ||
{ | ||
async Task F() | ||
{ | ||
foreach $$ } | ||
}", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestForeachStatement_TopLevel() | ||
{ | ||
await VerifyAbsenceAsync("foreach $$", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestNotInQuery() | ||
{ | ||
await VerifyAbsenceAsync(@" | ||
class C | ||
{ | ||
async Task F() | ||
{ | ||
var z = from a in ""char"" | ||
select $$ } | ||
} | ||
", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestNotInQuery_TopLevel() | ||
{ | ||
await VerifyAbsenceAsync( | ||
@"var z = from a in ""char"" | ||
select $$", LanguageVersion.CSharp9); | ||
} | ||
|
||
[WorkItem(907052, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/907052")] | ||
[Fact] | ||
public async Task TestInFinally() | ||
{ | ||
await VerifyKeywordAsync(@" | ||
class C | ||
{ | ||
async Task F() | ||
{ | ||
try { } | ||
finally { $$ } } | ||
}", LanguageVersion.CSharp9); | ||
} | ||
|
||
[WorkItem(907052, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/907052")] | ||
[Fact] | ||
public async Task TestInFinally_TopLevel() | ||
{ | ||
await VerifyKeywordAsync( | ||
@"try { } | ||
finally { $$ }", LanguageVersion.CSharp9); | ||
} | ||
|
||
[WorkItem(907052, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/907052")] | ||
[Fact] | ||
public async Task TestInCatch() | ||
{ | ||
await VerifyKeywordAsync(@" | ||
class C | ||
{ | ||
async Task F() | ||
{ | ||
try { } | ||
catch { $$ } } | ||
}", LanguageVersion.CSharp9); | ||
} | ||
|
||
[WorkItem(907052, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/907052")] | ||
[Fact] | ||
public async Task TestInCatch_TopLevel() | ||
{ | ||
await VerifyKeywordAsync( | ||
@"try { } | ||
catch { $$ }", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestNotInLock() | ||
{ | ||
await VerifyAbsenceAsync(@" | ||
class C | ||
{ | ||
async Task F() | ||
{ | ||
lock(this) { $$ } } | ||
}", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestNotInLock_TopLevel() | ||
{ | ||
await VerifyAbsenceAsync("lock (this) { $$ }", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestInAsyncLambdaInCatch() | ||
{ | ||
await VerifyKeywordAsync(@" | ||
class C | ||
{ | ||
async Task F() | ||
{ | ||
try { } | ||
catch { var z = async () => $$ } } | ||
}", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestInAsyncLambdaInCatch_TopLevel() | ||
{ | ||
await VerifyKeywordAsync( | ||
@"try { } | ||
catch { var z = async () => $$ }", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestAwaitInLock() | ||
{ | ||
await VerifyKeywordAsync(@" | ||
class C | ||
{ | ||
async Task F() | ||
{ | ||
lock($$ } | ||
}", LanguageVersion.CSharp9); | ||
} | ||
|
||
[Fact] | ||
public async Task TestAwaitInLock_TopLevel() | ||
{ | ||
await VerifyKeywordAsync("lock($$", LanguageVersion.CSharp9); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm surprised there is any langauge version specific code in this feature area.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CyrusNajmabadi This was a direct port from the deleted test file. The language version is used for top-level statement tests. See the current
AwaitKeywordRecommenderTests
in current main (this is being deleted in this PR - or essentially renamed toAwaitCompletionProviderTests
with some refactoring you requested and new tests (in addition to the integration tests added)