From 83f6a6304cae6657ba0397032714989405fbe933 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 26 Dec 2024 20:34:59 +1100 Subject: [PATCH] Avoid tail recursion in IsAsyncDisposeImplementation (#4432) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../IMethodSymbolExtensions.cs | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs index e308c35b21..617e8e255c 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs @@ -68,20 +68,24 @@ public static bool IsDisposeImplementation([NotNullWhen(returnValue: true)] this /// public static bool IsAsyncDisposeImplementation([NotNullWhen(returnValue: true)] this IMethodSymbol? method, [NotNullWhen(returnValue: true)] INamedTypeSymbol? iAsyncDisposable, [NotNullWhen(returnValue: true)] INamedTypeSymbol? valueTaskType) { - if (method == null) + while (true) { - return false; - } + if (method == null) + { + return false; + } - if (method.IsOverride) - { - return method.OverriddenMethod.IsAsyncDisposeImplementation(iAsyncDisposable, valueTaskType); - } + if (method.IsOverride) + { + method = method.OverriddenMethod; + continue; + } - // Identify the implementor of IAsyncDisposable.Dispose in the given method's containing type and check - // if it is the given method. - return SymbolEqualityComparer.Default.Equals(method.ReturnType, valueTaskType) && - method.Parameters.IsEmpty && - method.IsImplementationOfInterfaceMethod(null, iAsyncDisposable, "DisposeAsync"); + // Identify the implementor of IAsyncDisposable.Dispose in the given method's containing type and check + // if it is the given method. + return SymbolEqualityComparer.Default.Equals(method.ReturnType, valueTaskType) && + method.Parameters.IsEmpty && + method.IsImplementationOfInterfaceMethod(null, iAsyncDisposable, "DisposeAsync"); + } } }