From e31cb0c83680944e8c50c7c9fb0dfab424fbe801 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Thu, 15 Sep 2022 22:45:02 +0200 Subject: [PATCH] Do not remove async/await --- ChangeLog.md | 1 + .../Analysis/RemoveAsyncAwaitAnalysis.cs | 16 ++++++++++++- .../RCS1174RemoveRedundantAsyncAwaitTests.cs | 24 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 90790c6828..ac26e49dc2 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Prefix identifier with `@` if necessary ([RCS1220](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1220.md)) ([#943](https://github.com/josefpihrt/roslynator/pull/943). - Do not suggest to make local variable a const when it is used in ref extension method ([RCS1118](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1118.md)) ([#948](https://github.com/josefpihrt/roslynator/pull/948). - Fix formatting of argument list ([#952](https://github.com/josefpihrt/roslynator/pull/952). +- Do not remove async/await when 'using declaration' is used ([#953](https://github.com/josefpihrt/roslynator/pull/953). ----- diff --git a/src/Common/CSharp/Analysis/RemoveAsyncAwaitAnalysis.cs b/src/Common/CSharp/Analysis/RemoveAsyncAwaitAnalysis.cs index 2ff7677190..587f34f427 100644 --- a/src/Common/CSharp/Analysis/RemoveAsyncAwaitAnalysis.cs +++ b/src/Common/CSharp/Analysis/RemoveAsyncAwaitAnalysis.cs @@ -154,7 +154,21 @@ private static RemoveAsyncAwaitAnalysis AnalyzeMethodBody( { SyntaxList statements = body.Statements; - StatementSyntax statement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement)); + StatementSyntax statement = null; + + foreach (StatementSyntax s in statements) + { + if (s is LocalDeclarationStatementSyntax localDeclarationStatement + && localDeclarationStatement.UsingKeyword.IsKind(SyntaxKind.UsingKeyword)) + { + return default; + } + + if (!s.IsKind(SyntaxKind.LocalFunctionStatement)) + { + statement = s; + } + } if (statement == null) return default; diff --git a/src/Tests/Analyzers.Tests/RCS1174RemoveRedundantAsyncAwaitTests.cs b/src/Tests/Analyzers.Tests/RCS1174RemoveRedundantAsyncAwaitTests.cs index 9ea76e4d4a..5e45401cb7 100644 --- a/src/Tests/Analyzers.Tests/RCS1174RemoveRedundantAsyncAwaitTests.cs +++ b/src/Tests/Analyzers.Tests/RCS1174RemoveRedundantAsyncAwaitTests.cs @@ -970,6 +970,30 @@ async Task SwitchWithDefaultAsync() } } } +"); + } + + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.RemoveRedundantAsyncAwait)] + public async Task TestNoDiagnostic_UsingDeclaration() + { + await VerifyNoDiagnosticAsync(@" +using System; +using System.IO; +using System.Threading.Tasks; + +class C +{ + private async Task M() + { + using var stream = File.OpenRead(""""); + return await this.M2(stream); + } + + private Task M2(FileStream stream) + { + throw new NotImplementedException(); + } +} "); } }