diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Navigation/FindImplementationsService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Navigation/FindImplementationsService.cs index 2d8e198390..d2f40a73cd 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Navigation/FindImplementationsService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Navigation/FindImplementationsService.cs @@ -39,23 +39,25 @@ public async Task Handle(FindImplementationsRequest request) var quickFixes = new List(); var symbol = await SymbolFinder.FindSymbolAtPositionAsync(semanticModel, position, _workspace); - // SymbolFinder.FindImplementationsAsync will not include the method overrides - var implementations = await SymbolFinder.FindImplementationsAsync(symbol, _workspace.CurrentSolution); - foreach (var implementation in implementations) + if (symbol.IsInterfaceType() || symbol.IsImplementableMember()) { - quickFixes.Add(implementation, _workspace); - - if (implementation.IsOverridable()) + // SymbolFinder.FindImplementationsAsync will not include the method overrides + var implementations = await SymbolFinder.FindImplementationsAsync(symbol, _workspace.CurrentSolution); + foreach (var implementation in implementations) { - var overrides = await SymbolFinder.FindOverridesAsync(implementation, _workspace.CurrentSolution); - quickFixes.AddRange(overrides, _workspace); + quickFixes.Add(implementation, _workspace); + + if (implementation.IsOverridable()) + { + var overrides = await SymbolFinder.FindOverridesAsync(implementation, _workspace.CurrentSolution); + quickFixes.AddRange(overrides, _workspace); + } } } - - // for types also include derived classes - // for other symbols, find overrides and include those - if (symbol is INamedTypeSymbol namedTypeSymbol) + else if (symbol is INamedTypeSymbol namedTypeSymbol) { + // for types also include derived classes + // for other symbols, find overrides and include those var derivedTypes = await SymbolFinder.FindDerivedClassesAsync(namedTypeSymbol, _workspace.CurrentSolution); quickFixes.AddRange(derivedTypes, _workspace); } diff --git a/src/OmniSharp.Roslyn/Extensions/SymbolExtensions.cs b/src/OmniSharp.Roslyn/Extensions/SymbolExtensions.cs index f88079657a..df584c08e1 100644 --- a/src/OmniSharp.Roslyn/Extensions/SymbolExtensions.cs +++ b/src/OmniSharp.Roslyn/Extensions/SymbolExtensions.cs @@ -297,5 +297,38 @@ internal static string GetFilePathForExternalSymbol(this ISymbol symbol, Project } private static string Folderize(string path) => string.Join("/", path.Split('.')); + + public static bool IsInterfaceType(this ISymbol symbol) => (symbol as ITypeSymbol)?.IsInterfaceType() == true; + + public static bool IsInterfaceType(this ITypeSymbol symbol) => symbol?.TypeKind == TypeKind.Interface; + + public static bool IsImplementableMember(this ISymbol symbol) + { + if (symbol?.ContainingType?.TypeKind == TypeKind.Interface) + { + if (symbol.Kind == SymbolKind.Event) + { + return true; + } + + if (symbol.Kind == SymbolKind.Property) + { + return true; + } + + if (symbol.Kind == SymbolKind.Method) + { + var methodSymbol = (IMethodSymbol)symbol; + if (methodSymbol.MethodKind == MethodKind.Ordinary || + methodSymbol.MethodKind == MethodKind.PropertyGet || + methodSymbol.MethodKind == MethodKind.PropertySet) + { + return true; + } + } + } + + return false; + } } }