From ce8ca3dfa00e083ddcf9c2f13e6584c9cbf10bc4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 28 Nov 2024 23:55:54 -0800 Subject: [PATCH 1/2] Fix issue with explicit interface completion and static interface members --- ...citInterfaceTypeCompletionProviderTests.cs | 23 +++++++++++++++--- ...ExplicitInterfaceTypeCompletionProvider.cs | 24 ++++++------------- .../AbstractSymbolCompletionProvider.cs | 4 ---- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProviderTests.cs index 4c9491220a8cc..f2011c08858e5 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProviderTests.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Completion.Providers; @@ -14,7 +12,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionProviders; [Trait(Traits.Feature, Traits.Features.Completion)] -public class ExplicitInterfaceTypeCompletionProviderTests : AbstractCSharpCompletionProviderTests +public sealed class ExplicitInterfaceTypeCompletionProviderTests : AbstractCSharpCompletionProviderTests { internal override Type GetCompletionProviderType() => typeof(ExplicitInterfaceTypeCompletionProvider); @@ -358,4 +356,23 @@ class C : I await VerifyItemExistsAsync(markup, "I", displayTextSuffix: "<>"); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54005")] + public async Task TestWithStaticKeyword() + { + var markup = """ + interface I1 + { + + static abstract void M1(); + } + + class C1 : I1 + { + static void $$ + } + """; + + await VerifyItemExistsAsync(markup, "I1", displayTextSuffix: ""); + } } diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProvider.cs index ebba7628d849d..d81c1d8f34809 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProvider.cs @@ -22,17 +22,12 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers; -[ExportCompletionProvider(nameof(ExplicitInterfaceTypeCompletionProvider), LanguageNames.CSharp)] +[ExportCompletionProvider(nameof(ExplicitInterfaceTypeCompletionProvider), LanguageNames.CSharp), Shared] [ExtensionOrder(After = nameof(ExplicitInterfaceMemberCompletionProvider))] -[Shared] -internal sealed partial class ExplicitInterfaceTypeCompletionProvider : AbstractSymbolCompletionProvider +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed partial class ExplicitInterfaceTypeCompletionProvider() : AbstractSymbolCompletionProvider { - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public ExplicitInterfaceTypeCompletionProvider() - { - } - internal override string Language => LanguageNames.CSharp; public override bool IsInsertionTrigger(SourceText text, int insertedCharacterPosition, CompletionOptions options) @@ -124,19 +119,14 @@ protected override Task> GetSymbolsAsync( private static bool IsPreviousTokenValid(SyntaxToken tokenBeforeType) { - if (tokenBeforeType.Kind() == SyntaxKind.AsyncKeyword) - { + while (tokenBeforeType.Kind() is SyntaxKind.AsyncKeyword or SyntaxKind.StaticKeyword) tokenBeforeType = tokenBeforeType.GetPreviousToken(); - } + // Show us after the open brace for a class/struct/interface if (tokenBeforeType.Kind() == SyntaxKind.OpenBraceToken) - { - // Show us after the open brace for a class/struct/interface return IsClassOrStructOrInterfaceOrRecord(tokenBeforeType.GetRequiredParent()); - } - if (tokenBeforeType.Kind() is SyntaxKind.CloseBraceToken or - SyntaxKind.SemicolonToken) + if (tokenBeforeType.Kind() is SyntaxKind.CloseBraceToken or SyntaxKind.SemicolonToken) { // Check that we're after a class/struct/interface member. var memberDeclaration = tokenBeforeType.GetAncestor(); diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs index 9a7e27a3f107c..ac6430abf3672 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs @@ -25,10 +25,6 @@ namespace Microsoft.CodeAnalysis.Completion.Providers; internal abstract partial class AbstractSymbolCompletionProvider : LSPCompletionProvider where TSyntaxContext : SyntaxContext { - protected AbstractSymbolCompletionProvider() - { - } - protected abstract (string displayText, string suffix, string insertionText) GetDisplayAndSuffixAndInsertionText(ISymbol symbol, TSyntaxContext context); protected abstract Task> GetSymbolsAsync( From 0e605da7639d9a317c4466d396b62a51d3fd365b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 2 Dec 2024 10:05:54 -0800 Subject: [PATCH 2/2] Update src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProviderTests.cs --- .../ExplicitInterfaceTypeCompletionProviderTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProviderTests.cs index f2011c08858e5..c8e6f4c6a6781 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExplicitInterfaceTypeCompletionProviderTests.cs @@ -363,7 +363,6 @@ public async Task TestWithStaticKeyword() var markup = """ interface I1 { - static abstract void M1(); }