diff --git a/src/Analyzers/Core/Analyzers/RemoveUnusedMembers/AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/RemoveUnusedMembers/AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs index 864b0c21e66ad..f808c402b6c07 100644 --- a/src/Analyzers/Core/Analyzers/RemoveUnusedMembers/AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/RemoveUnusedMembers/AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs @@ -557,21 +557,14 @@ private void AnalyzeInvocationOperation(OperationAnalysisContext operationContex // If the invoked method is a reduced extension method, also mark the original // method from which it was reduced as "used". - if (targetMethod.ReducedFrom != null) - OnSymbolUsage(targetMethod.ReducedFrom, ValueUsageInfo.Read); + OnSymbolUsage(targetMethod.ReducedFrom, ValueUsageInfo.Read); // If the invoked method is an implementation method for an extension member, // also mark that extension member as "used". // If the extension member is an accessor, also mark its associated property as "used". - if (targetMethod.TryGetCorrespondingExtensionBlockMethod() is { } extensionBlockMethod) - { - OnSymbolUsage(extensionBlockMethod, ValueUsageInfo.Read); - - if (extensionBlockMethod.AssociatedSymbol is { } associatedSymbol) - { - OnSymbolUsage(associatedSymbol, ValueUsageInfo.Read); - } - } + var extensionBlockMethod = targetMethod.TryGetCorrespondingExtensionBlockMethod(); + OnSymbolUsage(extensionBlockMethod, ValueUsageInfo.Read); + OnSymbolUsage(extensionBlockMethod?.AssociatedSymbol, ValueUsageInfo.Read); } private void AnalyzeNameOfOperation(OperationAnalysisContext operationContext) @@ -820,11 +813,11 @@ private void AddCandidateSymbolsReferencedInDocComments( AddIfCandidateSymbol(builder, symbol); - if (symbol is IMethodSymbol methodSymbol - && methodSymbol.TryGetCorrespondingExtensionBlockMethod() is { } extensionBlockMethod) + if (symbol is IMethodSymbol methodSymbol) { + var extensionBlockMethod = methodSymbol.TryGetCorrespondingExtensionBlockMethod(); AddIfCandidateSymbol(builder, extensionBlockMethod); - AddIfCandidateSymbol(builder, extensionBlockMethod.AssociatedSymbol); + AddIfCandidateSymbol(builder, extensionBlockMethod?.AssociatedSymbol); } } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/IMethodSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/IMethodSymbolExtensions.cs index 86be9e8eba2e5..d79ea882a5eb0 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/IMethodSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/IMethodSymbolExtensions.cs @@ -18,26 +18,23 @@ internal static partial class IMethodSymbolExtensions #if !ROSLYN_4_12_OR_LOWER internal static IMethodSymbol? TryGetCorrespondingExtensionBlockMethod(this IMethodSymbol methodSymbol) { - if (methodSymbol is not { IsStatic: true, IsImplicitlyDeclared: true, ContainingType.MightContainExtensionMethods: true }) - return null; - - // Having a compiler API to go from implementation method back to its corresponding extension member would be useful - // Tracked by https://github.com/dotnet/roslyn/issues/81686 - - foreach (var nestedType in methodSymbol.ContainingType.GetTypeMembers()) + if (methodSymbol is { IsStatic: true, IsImplicitlyDeclared: true, ContainingType.MightContainExtensionMethods: true }) { - if (!nestedType.IsExtension || nestedType.ExtensionParameter is null) - continue; + // Having a compiler API to go from implementation method back to its corresponding extension member would be useful + // Tracked by https://github.com/dotnet/roslyn/issues/81686 - foreach (var member in nestedType.GetMembers()) + foreach (var nestedType in methodSymbol.ContainingType.GetTypeMembers()) { - if (member is IMethodSymbol method) - { - var associated = method.AssociatedExtensionImplementation; - if (!Equals(associated, methodSymbol)) - continue; + if (!nestedType.IsExtension || nestedType.ExtensionParameter is null) + continue; - return method; + foreach (var member in nestedType.GetMembers()) + { + if (member is IMethodSymbol method && + Equals(method.AssociatedExtensionImplementation, methodSymbol)) + { + return method; + } } } }