33// See the LICENSE file in the project root for more information.
44
55using System ;
6+ using System . Diagnostics . CodeAnalysis ;
67using System . Threading . Tasks ;
78using Microsoft . CodeAnalysis . CSharp ;
89using Microsoft . CodeAnalysis . CSharp . Completion . Providers ;
1415namespace Microsoft . CodeAnalysis . Editor . CSharp . UnitTests . Recommendations ;
1516
1617/// <summary>
17- /// The <see cref="AwaitCompletionProvider"/> adds async modifier if the return type is Task or ValueTask.
18- /// The tests here are only checking whether the completion item is provided or not.
19- /// Tests for checking adding async modifier are in:
20- /// src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests_AwaitCompletion.vb
18+ /// The <see cref="AwaitCompletionProvider"/> adds async modifier if the return type is Task or ValueTask. The tests
19+ /// here are only checking whether the completion item is provided or not. Tests for checking adding async modifier are
20+ /// in: src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests_AwaitCompletion.vb
2121/// </summary>
2222[ Trait ( Traits . Feature , Traits . Features . Completion ) ]
23- public class AwaitCompletionProviderTests : AbstractCSharpCompletionProviderTests
23+ public sealed class AwaitCompletionProviderTests : AbstractCSharpCompletionProviderTests
2424{
2525 internal override Type GetCompletionProviderType ( ) => typeof ( AwaitCompletionProvider ) ;
2626
2727 private const string CompletionDisplayTextAwait = "await" ;
2828 private const string CompletionDisplayTextAwaitAndConfigureAwait = "awaitf" ;
2929
30- private async Task VerifyAbsenceAsync ( string code )
30+ private async Task VerifyAbsenceAsync ( [ StringSyntax ( PredefinedEmbeddedLanguageNames . CSharpTest ) ] string code )
3131 {
3232 await VerifyItemIsAbsentAsync ( code , CompletionDisplayTextAwait ) ;
3333 await VerifyItemIsAbsentAsync ( code , CompletionDisplayTextAwaitAndConfigureAwait ) ;
3434 }
3535
36- private async Task VerifyAbsenceAsync ( string code , LanguageVersion languageVersion = LanguageVersion . Default )
36+ private async Task VerifyAbsenceAsync (
37+ [ StringSyntax ( PredefinedEmbeddedLanguageNames . CSharpTest ) ] string code , LanguageVersion languageVersion = LanguageVersion . Default )
3738 {
3839 await VerifyItemIsAbsentAsync ( GetMarkup ( code , languageVersion ) , CompletionDisplayTextAwait ) ;
3940 await VerifyItemIsAbsentAsync ( GetMarkup ( code , languageVersion ) , CompletionDisplayTextAwaitAndConfigureAwait ) ;
4041 }
4142
42- private async Task VerifyKeywordAsync ( string code , LanguageVersion languageVersion = LanguageVersion . Default , string ? inlineDescription = null , bool dotAwait = false , bool dotAwaitf = false )
43+ private async Task VerifyKeywordAsync (
44+ [ StringSyntax ( PredefinedEmbeddedLanguageNames . CSharpTest ) ] string code , LanguageVersion languageVersion = LanguageVersion . Default , string ? inlineDescription = null , bool dotAwait = false , bool dotAwaitf = false )
4345 {
4446 var expectedDescription = dotAwait
4547 ? GetDescription ( CompletionDisplayTextAwait , FeaturesResources . Await_the_preceding_expression )
@@ -351,24 +353,24 @@ async Task F(Task<int> someTask)
351353 public async Task TestDotAwaitSuggestAfterDotOnValueTask ( )
352354 {
353355 var valueTaskAssembly = typeof ( ValueTask ) . Assembly . Location ;
354- var markup = @$ "
355- <Workspace>
356- <Project Language="" C#"" AssemblyName="" Assembly1"" CommonReferences="" true" ">
357- <MetadataReference>{ valueTaskAssembly } </MetadataReference>
358- <Document FilePath="" Test2.cs" ">
359- using System.Threading.Tasks;
356+ var markup = $$ "" "
357+ <Workspace>
358+ <Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
359+ <MetadataReference>{{ valueTaskAssembly } } </MetadataReference>
360+ <Document FilePath="Test2.cs">
361+ using System.Threading.Tasks;
360362
361- class C
362- { {
363- async Task F(ValueTask someTask)
364- { {
365- someTask.$$
366- } }
367- } }
368- </Document>
369- </Project>
370- </Workspace>
371- " ;
363+ class C
364+ {
365+ async Task F(ValueTask someTask)
366+ {
367+ someTask.$$
368+ }
369+ }
370+ </Document>
371+ </Project>
372+ </Workspace>
373+ "" ";
372374 await VerifyItemExistsAsync ( markup , "await" ) ;
373375 await VerifyItemExistsAsync ( markup , "awaitf" ) ;
374376 }
@@ -499,18 +501,19 @@ async Task Test() { }
499501 [ InlineData ( "async Task<System.Int32> Test() => await Task.FromResult(1);" ) ]
500502 public async Task TestDotAwaitSuggestAfterDotBeforeDifferentStatements ( string statement )
501503 {
502- await VerifyKeywordAsync ( $@ "
503- using System;
504- using System.Threading.Tasks;
504+ await VerifyKeywordAsync ( $$ "" "
505+ using System;
506+ using System.Threading.Tasks;
505507
506- static class Program
507- {{
508- static async Task Main(Task someTask)
509- {{
510- someTask.$$
511- { statement }
512- }}
513- }}" , dotAwait : true , dotAwaitf : true ) ;
508+ static class Program
509+ {
510+ static async Task Main(Task someTask)
511+ {
512+ someTask.$$
513+ {{ statement }}
514+ }
515+ }
516+ """ , dotAwait : true , dotAwaitf : true ) ;
514517 }
515518
516519 [ Theory ]
@@ -546,38 +549,39 @@ static async Task Main(Task someTask)
546549 [ InlineData ( "(null ?? Task.CompletedTask).$$" ) ]
547550 public async Task TestDotAwaitSuggestAfterDifferentExpressions ( string expression )
548551 {
549- await VerifyKeywordAsync ( $@ "
550- using System;
551- using System.Threading.Tasks;
552+ await VerifyKeywordAsync ( $$ "" "
553+ using System;
554+ using System.Threading.Tasks;
552555
553- class C
554- { {
555- public C Self => this;
556- public Task Field = Task.CompletedTask;
557- public Task Method() => Task.CompletedTask;
558- public Task Property => Task.CompletedTask;
559- public Task this[int i] => Task.CompletedTask;
560- public Func<Task> Function() => () => Task.CompletedTask;
561- public static Task operator +(C left, C right) => Task.CompletedTask;
562- public static explicit operator Task(C c) => Task.CompletedTask;
563- } }
556+ class C
557+ {
558+ public C Self => this;
559+ public Task Field = Task.CompletedTask;
560+ public Task Method() => Task.CompletedTask;
561+ public Task Property => Task.CompletedTask;
562+ public Task this[int i] => Task.CompletedTask;
563+ public Func<Task> Function() => () => Task.CompletedTask;
564+ public static Task operator +(C left, C right) => Task.CompletedTask;
565+ public static explicit operator Task(C c) => Task.CompletedTask;
566+ }
564567
565- static class Program
566- { {
567- static Task StaticField = Task.CompletedTask;
568- static Task StaticProperty => Task.CompletedTask;
569- static Task StaticMethod() => Task.CompletedTask;
568+ static class Program
569+ {
570+ static Task StaticField = Task.CompletedTask;
571+ static Task StaticProperty => Task.CompletedTask;
572+ static Task StaticMethod() => Task.CompletedTask;
570573
571- static async Task Main(Task parameter)
572- { {
573- Task local = Task.CompletedTask;
574- var c = new C();
574+ static async Task Main(Task parameter)
575+ {
576+ Task local = Task.CompletedTask;
577+ var c = new C();
575578
576- { expression }
579+ {{ expression } }
577580
578- Task LocalFunction() => Task.CompletedTask;
579- }}
580- }}" , dotAwait : true , dotAwaitf : true ) ;
581+ Task LocalFunction() => Task.CompletedTask;
582+ }
583+ }
584+ """ , dotAwait : true , dotAwaitf : true ) ;
581585 }
582586
583587 [ Fact ( Skip = "Fails because speculative binding can't figure out that local is a Task." ) ]
@@ -618,17 +622,18 @@ static async Task Main()
618622 [ InlineData ( "await Task.Run(() => someTask.$$" ) ]
619623 public async Task TestDotAwaitSuggestInLambdas ( string lambda )
620624 {
621- await VerifyKeywordAsync ( $@ "
622- using System.Threading.Tasks;
625+ await VerifyKeywordAsync ( $$ "" "
626+ using System.Threading.Tasks;
623627
624- static class Program
625- {{
626- static async Task Main()
627- {{
628- var someTask = Task.CompletedTask;
629- { lambda }
630- }}
631- }}" , dotAwait : true , dotAwaitf : true ) ;
628+ static class Program
629+ {
630+ static async Task Main()
631+ {
632+ var someTask = Task.CompletedTask;
633+ {{ lambda }}
634+ }
635+ }
636+ """ , dotAwait : true , dotAwaitf : true ) ;
632637 }
633638
634639 [ Fact ]
@@ -854,25 +859,25 @@ async Task F(Task someTask)
854859 [ InlineData ( "new C().M()?.Pro.M()?.M().SomeTask.$$" ) ]
855860 public async Task TestDotAwaitNotAfterDotInConditionalAccessChain ( string conditionalAccess )
856861 {
857- await VerifyAbsenceAsync ( $@ "
858- using System.Threading.Tasks;
859- public class C
860- { {
861- public Task SomeTask => Task.CompletedTask;
862-
863- public C Pro => this;
864- public C M() => this;
865- } }
866-
867- static class Program
868- { {
869- public static async Task Main()
870- { {
871- var c = new C();
872- { conditionalAccess }
873- } }
874- } }
875- " ) ;
862+ await VerifyAbsenceAsync ( $$ "" "
863+ using System.Threading.Tasks;
864+ public class C
865+ {
866+ public Task SomeTask => Task.CompletedTask;
867+
868+ public C Pro => this;
869+ public C M() => this;
870+ }
871+
872+ static class Program
873+ {
874+ public static async Task Main()
875+ {
876+ var c = new C();
877+ {{ conditionalAccess } }
878+ }
879+ }
880+ "" ") ;
876881 }
877882
878883 [ Theory ]
@@ -895,41 +900,42 @@ public static async Task Main()
895900 [ InlineData ( "new C().M()!.Pro.M()!.M().SomeTask.$$" ) ]
896901 public async Task TestDotAwaitAfterNullForgivingOperatorAccessChain ( string nullForgivingAccess )
897902 {
898- await VerifyKeywordAsync ( $@ "
899- #nullable enable
903+ await VerifyKeywordAsync ( $$ "" "
904+ #nullable enable
900905
901- using System.Threading.Tasks;
902- public class C
903- { {
904- public Task? SomeTask => Task.CompletedTask;
905-
906- public C? Pro => this;
907- public C? M() => this;
908- } }
909-
910- static class Program
911- { {
912- public static async Task Main(params string[] args)
913- { {
914- var c = args[1] == string.Empty ? new C() : null;
915- { nullForgivingAccess }
916- } }
917- } }
918- " , dotAwait : true , dotAwaitf : true ) ;
906+ using System.Threading.Tasks;
907+ public class C
908+ {
909+ public Task? SomeTask => Task.CompletedTask;
910+
911+ public C? Pro => this;
912+ public C? M() => this;
913+ }
914+
915+ static class Program
916+ {
917+ public static async Task Main(params string[] args)
918+ {
919+ var c = args[1] == string.Empty ? new C() : null;
920+ {{ nullForgivingAccess } }
921+ }
922+ }
923+ "" ", dotAwait : true , dotAwaitf : true ) ;
919924 }
920925
921926 [ Theory , CombinatorialData ]
922927 [ WorkItem ( "https://github.com/dotnet/roslyn/issues/58921" ) ]
923928 public async Task TestInCastExpressionThatMightBeParenthesizedExpression ( bool hasNewline )
924929 {
925- var code = $@ "
926- class C
927- {{
928- void M()
929- {{
930- var data = (n$$) { ( hasNewline ? Environment . NewLine : string . Empty ) } M();
931- }}
932- }}" ;
930+ var code = $$ """
931+ class C
932+ {
933+ void M()
934+ {
935+ var data = (n$$) {{ ( hasNewline ? Environment . NewLine : string . Empty ) }} M();
936+ }
937+ }
938+ """ ;
933939 if ( hasNewline )
934940 await VerifyKeywordAsync ( code ) ;
935941 else
0 commit comments