From 690c9ab4c138b1c71bfad6377d4180857ee1c0a8 Mon Sep 17 00:00:00 2001 From: Paul Chen Date: Thu, 24 Sep 2015 00:54:28 +0800 Subject: [PATCH] Special casing for single line ternary expressions that without singleline comments in C# --- .../Diagnostics/Async/AddAwaitTests.cs | 136 +++++++++++++++++- .../Async/CSharpAddAwaitCodeFixProvider.cs | 11 ++ 2 files changed, 144 insertions(+), 3 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAwaitTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAwaitTests.cs index 93f49ce1c5a..8602a60ec94 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAwaitTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/Async/AddAwaitTests.cs @@ -90,7 +90,7 @@ async Task Test2() } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)] - public void BadAsyncReturnOperand_WithTrailingTrivia1() + public void BadAsyncReturnOperand_ConditionalExpressionWithTrailingTrivia_SingleLine() { var initial = @"using System.Threading.Tasks; @@ -114,14 +114,14 @@ class Program async Task Test2() { - return await (true ? Test() /* true */ : Test()) /* false */; + return await (true ? Test() /* true */ : Test() /* false */); } }"; Test(initial, expected, compareTokens: false); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)] - public void BadAsyncReturnOperand_WithTrailingTrivia2() + public void BadAsyncReturnOperand_ConditionalExpressionWithTrailingTrivia_Multiline() { var initial = @"using System.Threading.Tasks; @@ -155,6 +155,136 @@ async Task Test2() Test(initial, expected, compareTokens: false); } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)] + public void BadAsyncReturnOperand_NullCoalescingExpressionWithTrailingTrivia_SingleLine() + { + var initial = +@"using System.Threading.Tasks; + +class Program +{ + async Task Test() => 3; + + async Task Test2() + {[| + return null /* 0 */ ?? Test() /* 1 */; + |]} +}"; + + var expected = +@"using System.Threading.Tasks; + +class Program +{ + async Task Test() => 3; + + async Task Test2() + { + return await (null /* 0 */ ?? Test() /* 1 */); + } +}"; + Test(initial, expected, compareTokens: false); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)] + public void BadAsyncReturnOperand_NullCoalescingExpressionWithTrailingTrivia_Multiline() + { + var initial = +@"using System.Threading.Tasks; + +class Program +{ + async Task Test() => 3; + + async Task Test2() + {[| + return null // aaa + ?? Test() // bbb + ; + |]} +}"; + + var expected = +@"using System.Threading.Tasks; + +class Program +{ + async Task Test() => 3; + + async Task Test2() + { + return await (null // aaa + ?? Test()) // bbb + ; + } +}"; + Test(initial, expected, compareTokens: false); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)] + public void BadAsyncReturnOperand_AsExpressionWithTrailingTrivia_SingleLine() + { + var initial = +@"using System.Threading.Tasks; + +class Program +{ + async Task Test2() + {[| + return null /* 0 */ as Task /* 1 */; + |]} +}"; + + var expected = +@"using System.Threading.Tasks; + +class Program +{ + async Task Test() => 3; + + async Task Test2() + { + return await (null /* 0 */ as Task /* 1 */); + } +}"; + Test(initial, expected, compareTokens: false); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)] + public void BadAsyncReturnOperand_AsExpressionWithTrailingTrivia_Multiline() + { + var initial = +@"using System.Threading.Tasks; + +class Program +{ + async Task Test() => 3; + + async Task Test2() + {[| + return null // aaa + as Task // bbb + ; + |]} +}"; + + var expected = +@"using System.Threading.Tasks; + +class Program +{ + async Task Test() => 3; + + async Task Test2() + { + return await (null // aaa + as Task) // bbb + ; + } +}"; + Test(initial, expected, compareTokens: false); + } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)] public void TaskNotAwaited() { diff --git a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs index ce72878ba3f..75688095d9c 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs @@ -148,6 +148,17 @@ private static bool IsInAsyncFunction(ExpressionSyntax expression) private static SyntaxNode ConvertToAwaitExpression(ExpressionSyntax expression) { + if ((expression is BinaryExpressionSyntax || expression is ConditionalExpressionSyntax) && expression.HasTrailingTrivia) + { + var expWithTrailing = expression.WithoutLeadingTrivia(); + var span = expWithTrailing.GetLocation().GetLineSpan().Span; + if (span.Start.Line == span.End.Line && !expWithTrailing.DescendantTrivia().Any(trivia => trivia.IsKind(SyntaxKind.SingleLineCommentTrivia))) + { + return SyntaxFactory.AwaitExpression(SyntaxFactory.ParenthesizedExpression(expWithTrailing)) + .WithLeadingTrivia(expression.GetLeadingTrivia()) + .WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation); + } + } return SyntaxFactory.AwaitExpression(expression.WithoutTrivia().Parenthesize()) .WithTriviaFrom(expression) .WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation); -- GitLab