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

Add async modifier on await completion #48352

Merged
merged 45 commits into from
Jul 16, 2021
Merged
Show file tree
Hide file tree
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 Oct 6, 2020
60f8850
Localize and sealed
Youssef1313 Mar 6, 2021
447f01f
Fixes
Youssef1313 Mar 6, 2021
5938d3d
Use GetRequiredSemanticModelAsync instead
Youssef1313 Mar 6, 2021
73f43bb
Update CompletionProviderOrderTests.cs
Youssef1313 Mar 6, 2021
854945e
Merge branch 'main' into await-completion
Youssef1313 Mar 20, 2021
994932f
Make single completion provider for await
Youssef1313 Mar 25, 2021
1902c94
Tests
Youssef1313 Mar 25, 2021
39a17aa
Remove #nullable disable
Youssef1313 Mar 25, 2021
a39c348
Tests and not use field in completion provider
Youssef1313 Mar 25, 2021
50ca76e
Introduce a language service to share common code
Youssef1313 Mar 26, 2021
36b1ac8
Comments
Youssef1313 Mar 26, 2021
a5eeb67
Clean tests
Youssef1313 Mar 26, 2021
0431d4a
Fix NRE
Youssef1313 Mar 26, 2021
71cce7f
Fix
Youssef1313 Mar 30, 2021
c4aa2bb
Address feedback
Youssef1313 Mar 31, 2021
8cfc8f9
Test glyph and inline description in unit tests
Youssef1313 Mar 31, 2021
45a9f6b
Support anonymous functions
Youssef1313 Mar 31, 2021
77bf329
Fix
Youssef1313 Mar 31, 2021
0caf239
Rename test class
Youssef1313 Mar 31, 2021
61a0823
Fix failing test
Youssef1313 Mar 31, 2021
2f68771
Fix TestCompletionProviderOrderMetadata
Youssef1313 Mar 31, 2021
408eed7
Move to KnownTaskTypes
Youssef1313 Apr 1, 2021
60b0f5a
Merge branch 'main' into await-completion
Youssef1313 Apr 22, 2021
6a8534e
Merge branch 'main' into await-completion
Youssef1313 Apr 25, 2021
bf2ccad
Fix
Youssef1313 May 4, 2021
4626e1c
Merge remote-tracking branch 'upstream/main' into await-completion
Youssef1313 May 4, 2021
b581185
Address feedback: override the public overload
Youssef1313 May 6, 2021
2f921c3
Add async regardless return type
Youssef1313 May 6, 2021
a4b7a01
Update VisualBasicMakeMethodSynchronousCodeFixProvider.vb
Youssef1313 May 6, 2021
cf21c76
Update VisualBasicMakeMethodAsynchronousCodeFixProvider.vb
Youssef1313 May 6, 2021
f82655c
Fix
Youssef1313 May 6, 2021
6324aba
Fix test
Youssef1313 May 6, 2021
d501fee
Fix tests
Youssef1313 May 6, 2021
9204341
Fix test
Youssef1313 May 6, 2021
d48175c
Merge remote-tracking branch 'upstream/main' into await-completion
Youssef1313 May 7, 2021
c5f219a
Handle trivia
Youssef1313 May 7, 2021
de41203
Fix
Youssef1313 May 7, 2021
f4bcff7
Fix
Youssef1313 May 7, 2021
7546e52
Fix
Youssef1313 May 7, 2021
ee6d1cc
Merge branch 'main' into await-completion
Youssef1313 Jun 20, 2021
2e2f041
Address feedback
Youssef1313 Jun 30, 2021
d259bc9
Merge remote-tracking branch 'upstream/main' into await-completion
Youssef1313 Jun 30, 2021
a376f7c
Handle explicit lambda return type
Youssef1313 Jun 30, 2021
8f85b57
Fix tests
Youssef1313 Jul 9, 2021
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 @@ -8,6 +8,7 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Completion;
using Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.AsyncCompletion;
using Microsoft.CodeAnalysis.Editor.UnitTests.Completion;
Expand All @@ -27,6 +28,15 @@ public abstract class AbstractCSharpCompletionProviderTests<TWorkspaceFixture> :
{
protected const string NonBreakingSpaceString = "\x00A0";

protected static string GetMarkup(string source, LanguageVersion languageVersion)
=> $@"<Workspace>
<Project Language=""C#"" AssemblyName=""Assembly1"" CommonReferences=""true"" LanguageVersion=""{languageVersion.ToDisplayString()}"">
<Document FilePath=""Test2.cs"">
{source}
</Document>
</Project>
</Workspace>";

protected override TestWorkspace CreateWorkspace(string fileContents)
=> TestWorkspace.CreateCSharp(fileContents, exportProvider: ExportProvider);

Expand Down
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)
Copy link
Member

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.

Copy link
Member Author

@Youssef1313 Youssef1313 May 5, 2021

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 to AwaitCompletionProviderTests with some refactoring you requested and new tests (in addition to the integration tests added)

{
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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public void TestCompletionProviderOrder()
typeof(AttributeNamedParameterCompletionProvider),
typeof(NamedParameterCompletionProvider),
typeof(KeywordCompletionProvider),
typeof(AwaitCompletionProvider),
typeof(SpeculativeTCompletionProvider),
typeof(SymbolCompletionProvider),
typeof(UnnamedSymbolCompletionProvider),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2715,14 +2715,5 @@ private static SerializableNamingRule CreateRule(SymbolSpecification specificati
EnforcementLevel = ReportDiagnostic.Error
};
}

private static string GetMarkup(string source, LanguageVersion languageVersion)
=> $@"<Workspace>
<Project Language=""C#"" AssemblyName=""Assembly1"" CommonReferences=""true"" LanguageVersion=""{languageVersion.ToDisplayString()}"">
<Document FilePath=""Test2.cs"">
{source}
</Document>
</Project>
</Workspace>";
}
}
Loading