diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ObjectInitializerCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ObjectInitializerCompletionProviderTests.cs index 9d6cecc8dcbc05be35d923d57dde465aa9faf92c..b51dfb66f464f31bfe1e80be104453abf149e9d1 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ObjectInitializerCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ObjectInitializerCompletionProviderTests.cs @@ -698,8 +698,9 @@ static void Main(string[] args) } }"; - await VerifyItemIsAbsentAsync(markup, "S"); - await VerifyItemIsAbsentAsync(markup, "D"); + // Can't use S={3}, but the object initializer syntax S={} is still valid + await VerifyItemExistsAsync(markup, "S"); + await VerifyItemExistsAsync(markup, "D"); } [WorkItem(13158, "https://github.com/dotnet/roslyn/issues/13158")] @@ -1015,7 +1016,7 @@ static void Main(string[] args) } }"; - await VerifyItemIsAbsentAsync(markup, "PropB"); + await VerifyItemExistsAsync(markup, "PropB"); } private async Task VerifyExclusiveAsync(string markup, bool exclusive) diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractObjectInitializerCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractObjectInitializerCompletionProvider.cs index d625d3e386c36a09a72409cd38b511adfe66b183..bc1887e099d5a49a67f37e6b713905f5d4f66631 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractObjectInitializerCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractObjectInitializerCompletionProvider.cs @@ -3,11 +3,13 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Completion.Providers { @@ -78,7 +80,10 @@ protected override Task GetDescriptionWorkerAsync(Documen protected abstract Task IsExclusiveAsync(Document document, int position, CancellationToken cancellationToken); private bool IsLegalFieldOrProperty(ISymbol symbol, ISymbol within) - => CanSupportCollectionInitializer(symbol, within) || symbol.IsWriteableFieldOrProperty() || CanSupportObjectInitializer(symbol, within); + { + return symbol.IsWriteableFieldOrProperty() + || CanSupportObjectInitializer(symbol, within); + } private static readonly CompletionItemRules s_rules = CompletionItemRules.Create(enterKeyRule: EnterKeyRule.Never); @@ -92,39 +97,18 @@ protected virtual bool IsInitializable(ISymbol member, INamedTypeSymbol containi private static bool CanSupportObjectInitializer(ISymbol symbol, ISymbol within) { - if (symbol is IPropertySymbol propertySymbol) + Debug.Assert(!symbol.IsWriteableFieldOrProperty(), "Assertion failed - expected writable field/property check before calling this method."); + + if (symbol is IFieldSymbol fieldSymbol) { - return propertySymbol.GetMethod != null && !propertySymbol.Type.IsStructType() && HasAccesseblePropertiesOrFields(propertySymbol.Type, within); + return !fieldSymbol.Type.IsStructType(); } - - return false; - } - - private static bool HasAccesseblePropertiesOrFields(ITypeSymbol type, ISymbol within) - { - var types = new HashSet(); - return HasAccesseblePropertiesOrFields(type, types); - - bool HasAccesseblePropertiesOrFields(ITypeSymbol typeToCheck, HashSet alreadyCheckedTypes) + else if (symbol is IPropertySymbol propertySymbol) { - if (alreadyCheckedTypes.Contains(typeToCheck)) - { - return false; - } - - alreadyCheckedTypes.Add(typeToCheck); - return typeToCheck.GetBaseTypesAndThis().SelectMany(x => x.GetMembers()) - .Where(member => member is IPropertySymbol || member is IFieldSymbol) - .Any(member => member.IsWriteableFieldOrProperty() || - CanSupportCollectionInitializer(member, within) || - HasAccesseblePropertiesOrFields(member.GetMemberType(), alreadyCheckedTypes)); + return !propertySymbol.Type.IsStructType(); } - } - private static bool CanSupportCollectionInitializer(ISymbol symbol, ISymbol within) - { - var type = symbol.GetMemberType(); - return type != null && type.CanSupportCollectionInitializer(within); + throw ExceptionUtilities.Unreachable; } } }