From 8dd6d839d24b5352c5ba748e83ea733a1e32a14e Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Thu, 17 Aug 2023 14:18:09 -0600 Subject: [PATCH] Remove catch TaskCanceledException when Generating --- .../Generator/AsyncToSyncMethodTransformer.cs | 25 ++++++++++--- .../AsyncToSyncMethodTransformerTests.cs | 36 +++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/D2L.CodeStyle.Analyzers/Async/Generator/AsyncToSyncMethodTransformer.cs b/src/D2L.CodeStyle.Analyzers/Async/Generator/AsyncToSyncMethodTransformer.cs index 21b74a6f..d18aea0e 100644 --- a/src/D2L.CodeStyle.Analyzers/Async/Generator/AsyncToSyncMethodTransformer.cs +++ b/src/D2L.CodeStyle.Analyzers/Async/Generator/AsyncToSyncMethodTransformer.cs @@ -124,6 +124,8 @@ private TypeSyntax TransformType( TypeSyntax typeSynt, bool isReturnType = false return ( (GenericNameSyntax)typeSynt ) .TypeArgumentList.Arguments.First() .WithTriviaFrom( typeSynt ); + case "TaskCanceledException": + return typeSynt; default: GeneratorError( @@ -189,9 +191,7 @@ private StatementSyntax Transform( StatementSyntax stmt ) LocalDeclarationStatementSyntax localDeclStmt => localDeclStmt .WithDeclaration( Transform( localDeclStmt.Declaration ) ), - TryStatementSyntax tryStmt => tryStmt - .WithBlock( Transform( tryStmt.Block ) ) - .WithCatches( TransformAll( tryStmt.Catches, Transform ) ), + TryStatementSyntax tryStmt => Transform( tryStmt ), ForEachStatementSyntax forEachStmt => forEachStmt .WithType( TransformType( forEachStmt.Type ) ) @@ -435,6 +435,17 @@ private VariableDeclarationSyntax Transform( VariableDeclarationSyntax varDecl ) .WithVariables( TransformVariables( varDecl.Variables ) ); } + private StatementSyntax Transform( TryStatementSyntax tryStmt ) { + var block = Transform( tryStmt.Block ); + var catches = TransformAll( tryStmt.Catches, Transform ); + + if( catches.Count == 0 ) { + return block; + } else { + return tryStmt.WithBlock( block ).WithCatches( catches ); + } + } + private SeparatedSyntaxList TransformVariables( SeparatedSyntaxList varDecls ) { return SyntaxFactory.SeparatedList( varDecls.Select( varDecl => @@ -514,10 +525,14 @@ private ParameterSyntax Transform( ParameterSyntax parameter ) { return parameter.WithIdentifier( RemoveAsyncSuffix( parameter.Identifier, optional: true ) ); } - private CatchClauseSyntax Transform( CatchClauseSyntax catchClause ) { - return catchClause + private CatchClauseSyntax? Transform( CatchClauseSyntax catchClause ) { + catchClause = catchClause .WithDeclaration( catchClause.Declaration != null ? Transform( catchClause.Declaration ) : null ) .WithBlock( Transform( catchClause.Block ) ); + if( !m_disableTaskRunWarningFlag && catchClause.Declaration?.Type.ToString() == "TaskCanceledException" ) { + return null; + } + return catchClause; } private CatchDeclarationSyntax Transform( CatchDeclarationSyntax catchDecl ) { diff --git a/tests/D2L.CodeStyle.Analyzers.Test/Async/Generator/AsyncToSyncMethodTransformerTests.cs b/tests/D2L.CodeStyle.Analyzers.Test/Async/Generator/AsyncToSyncMethodTransformerTests.cs index 961d0cb5..00a5141b 100644 --- a/tests/D2L.CodeStyle.Analyzers.Test/Async/Generator/AsyncToSyncMethodTransformerTests.cs +++ b/tests/D2L.CodeStyle.Analyzers.Test/Async/Generator/AsyncToSyncMethodTransformerTests.cs @@ -448,6 +448,42 @@ public void StringInterpolationExpression() { Assert.AreEqual( @"[Blocking] void Bar() { Console.WriteLine($""Hello, {GetUsername()}! Welcome back to {m_baz}, it is {GetTime()} {m_ampm}.""); }", actual.Value.ToFullString() ); } + [Test] + public void TaskCanceledException() { + var actual = Transform( @"[GenerateSync] async Task BarAsync() { try { response = await GetBazAsync().ConfigureAwait( false ); } catch( TaskCanceledException exception ) { Console.WriteLine( ""Failed"" ); } }" ); + + Assert.IsTrue( actual.Success ); + Assert.IsEmpty( actual.Diagnostics ); + Assert.AreEqual( @"[Blocking] void Bar() { { response = GetBaz(); } }", actual.Value.ToFullString() ); + } + + [Test] + public void TaskCanceledExceptionAndOthers() { + var actual = Transform( @"[GenerateSync] async Task BarAsync() { try { response = await GetBazAsync().ConfigureAwait( false ); } catch( TaskCanceledException exception ) { Console.WriteLine( ""Failed"" ); } catch ( IndexOutOfRangeException ) { Console.WriteLine( ""Index out of range"" ); } }" ); + + Assert.IsTrue( actual.Success ); + Assert.IsEmpty( actual.Diagnostics ); + Assert.AreEqual( @"[Blocking] void Bar() { try { response = GetBaz(); } catch ( IndexOutOfRangeException ) { Console.WriteLine( ""Index out of range"" ); } }", actual.Value.ToFullString() ); + } + + [Test] + public void TaskCanceledExceptionWhenWrappedInTaskRun() { + var actual = Transform( @"[GenerateSync] async Task BarAsync() { try { json = await m_response.Content.ReadAsStringAsync().ConfigureAwait( false ); } catch( TaskCanceledException exception ) { Console.WriteLine( ""Failed"" ); } }" ); + + Assert.IsTrue( actual.Success ); + Assert.IsEmpty( actual.Diagnostics ); + Assert.AreEqual( "#pragma warning disable D2L0018\r\n[Blocking] void Bar() { try { json = Task.Run(() => m_response.Content.ReadAsStringAsync()).Result; } catch( TaskCanceledException exception ) { Console.WriteLine( \"Failed\" ); } }\n#pragma warning restore D2L0018\r\n", actual.Value.ToFullString() ); + } + + [Test] + public void NotTaskCanceledException() { + var actual = Transform( @"[GenerateSync] async Task BarAsync() { TaskCancelledException e = default; try { response = await GetBazAsync().ConfigureAwait( false ); } catch( Exception exception ) { Console.WriteLine( ""Failed"" ); } }" ); + + Assert.IsTrue( actual.Success ); + Assert.IsEmpty( actual.Diagnostics ); + Assert.AreEqual( @"[Blocking] void Bar() { TaskCancelledException e = default; try { response = GetBaz(); } catch( Exception exception ) { Console.WriteLine( ""Failed"" ); } }", actual.Value.ToFullString() ); + } + [Test] public void Silly() { var actual = Transform( @"[GenerateSync]