Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14333,4 +14333,43 @@ class Foo2 { }
}
""", commitChar: commitChar, sourceCodeKind: SourceCodeKind.Regular);
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78766")]
public async Task ExtensionMethodAndPropertyWithSameName()
{
var markup = """
using NS1;

var x = new MyClass();
x.$$

namespace NS1
{
public class MyClass
{
public int MyMember { get; set; }
}

public static class Extensions
{
public static MyClass MyMember(this MyClass c)
=> c;
}
}
""";

MarkupTestFile.GetPosition(markup, out var code, out int position);

using var workspace = EditorTestWorkspace.CreateCSharp(code);
var document = workspace.CurrentSolution.Projects.First().Documents.First();

var service = GetCompletionService(document.Project);
var completionList = await GetCompletionListAsync(service, document, position, Microsoft.CodeAnalysis.Completion.CompletionTrigger.Invoke);

var myMemberItems = completionList.ItemsList.Where(item => item.DisplayText == "MyMember").ToList();

// We should have two separate completion items for MyMember:
// one for the property and one for the extension method
Assert.Equal(2, myMemberItems.Count);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,21 @@ private ImmutableArray<CompletionItem> CreateItems(
// Use SymbolReferenceEquivalenceComparer.Instance as the value comparer as we
// don't want symbols with just the same name to necessarily match
// (as the default comparer on SymbolAndSelectionInfo does)
var symbolGroups = new MultiDictionary<(string displayText, string suffix, string insertionText), SymbolAndSelectionInfo>(
//
// Include whether the symbol is a method in the key to avoid merging methods with non-methods
// that have the same name (e.g., a property and an extension method with the same name).
// https://github.com/dotnet/roslyn/issues/78766
var symbolGroups = new MultiDictionary<(string displayText, string suffix, string insertionText, bool isMethod), SymbolAndSelectionInfo>(
capacity: symbols.Length,
comparer: EqualityComparer<(string, string, string)>.Default,
comparer: EqualityComparer<(string, string, string, bool)>.Default,
valueComparer: SymbolReferenceEquivalenceComparer.Instance);

foreach (var symbol in symbols)
{
var texts = GetDisplayAndSuffixAndInsertionText(symbol.Symbol, contextLookup(symbol));
if (!string.IsNullOrWhiteSpace(texts.displayText))
{
symbolGroups.Add(texts, symbol);
symbolGroups.Add((texts.displayText, texts.suffix, texts.insertionText, symbol.Symbol.Kind == SymbolKind.Method), symbol);
}
}

Expand Down
Loading