diff --git a/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb b/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb index 5a12ebcc98c89..961a3ecc70c95 100644 --- a/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb +++ b/src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb @@ -12998,6 +12998,32 @@ public class Class1 End Using End Function + + + Public Async Function TestStaticExtensionMethod_OnEnumType(showCompletionInArgumentLists As Boolean) As Task + Using state = TestStateFactory.CreateCSharpTestState( + + using System; + + E.$$ + + enum E; + + static class C + { + extension(E) + { + public static void EM() { } + } + } + , + showCompletionInArgumentLists:=showCompletionInArgumentLists, languageVersion:=LanguageVersionExtensions.CSharpNext) + + state.SendInvokeCompletionList() + Await state.AssertCompletionItemsContain("EM", displayTextSuffix:="") + End Using + End Function + Public Async Function TestOverrideInstanceAssignmentOperator(showCompletionInArgumentLists As Boolean) As Task diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs index e2df9715a7438..6a49dd5478137 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs @@ -23,10 +23,12 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers; -[ExportCompletionProvider(nameof(EnumAndCompletionListTagCompletionProvider), LanguageNames.CSharp)] +[ExportCompletionProvider(nameof(EnumAndCompletionListTagCompletionProvider), LanguageNames.CSharp), Shared] [ExtensionOrder(After = nameof(CSharpSuggestionModeCompletionProvider))] -[Shared] -internal sealed partial class EnumAndCompletionListTagCompletionProvider : LSPCompletionProvider +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed partial class EnumAndCompletionListTagCompletionProvider() + : LSPCompletionProvider { private static readonly CompletionItemRules s_enumTypeRules = CompletionItemRules.Default.WithCommitCharacterRules([CharacterSetModificationRule.Create(CharacterSetModificationKind.Replace, '.')]) @@ -35,12 +37,6 @@ internal sealed partial class EnumAndCompletionListTagCompletionProvider : LSPCo private static readonly ImmutableHashSet s_triggerCharacters = [' ', '[', '(', '~']; - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public EnumAndCompletionListTagCompletionProvider() - { - } - internal override string Language => LanguageNames.CSharp; public override bool IsInsertionTrigger(SourceText text, int characterPosition, CompletionOptions options) @@ -105,7 +101,12 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) } private static async Task HandleSingleTypeAsync( - CompletionContext context, SemanticModel semanticModel, SyntaxToken token, ITypeSymbol type, bool isParams, CancellationToken cancellationToken) + CompletionContext context, + SemanticModel semanticModel, + SyntaxToken token, + ITypeSymbol type, + bool isParams, + CancellationToken cancellationToken) { if (isParams && type is IArrayTypeSymbol arrayType) type = arrayType.ElementType; diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs index 2bf2bbb952136..1984c03c685f2 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs @@ -13,7 +13,6 @@ using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis.Shared.Collections; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery; using Microsoft.CodeAnalysis.Shared.Utilities; diff --git a/src/Workspaces/Core/Portable/Recommendations/AbstractRecommendationService.cs b/src/Workspaces/Core/Portable/Recommendations/AbstractRecommendationService.cs index 04f43188acc64..dc97e88ba7ba0 100644 --- a/src/Workspaces/Core/Portable/Recommendations/AbstractRecommendationService.cs +++ b/src/Workspaces/Core/Portable/Recommendations/AbstractRecommendationService.cs @@ -113,7 +113,9 @@ internal bool ShouldIncludeSymbol(ISymbol symbol) if (_context.IsEnumTypeMemberAccessContext) { - return symbol.Kind == SymbolKind.Field; + // Within an enum type, we can access fields of the enum, as well as static extensions on that type. + return symbol.Kind == SymbolKind.Field || + symbol is { IsStatic: true, ContainingType.IsExtension: true }; } // In an expression or statement context, we don't want to display instance members declared in outer containing types.