Repository: dotnet/roslyn
File: src/Features/Core/Portable/Completion/Providers/AbstractSymbolCompletionProvider.cs (C#)

Code before:

        using var _ = ArrayBuilder<CompletionItem>.GetInstance(out var itemListBuilder);
        var typeConvertibilityCache = new Dictionary<ITypeSymbol, bool>(SymbolEqualityComparer.Default);

        foreach (var symbolGroup in symbolGroups)
        {
            var includeItemInTargetTypedCompletion = false;
            using var symbolListBuilder = TemporaryArray<SymbolAndSelectionInfo>.Empty;
            foreach (var symbol in symbolGroup.Value)
                symbolListBuilder.Add(symbol);

            var symbolList = symbolListBuilder.ToImmutableAndClear();
            var arbitraryFirstContext = contextLookup(symbolList[0]);

            if (completionContext.CompletionOptions.TargetTypedCompletionFilter)
            {
                includeItemInTargetTypedCompletion = TryFindFirstSymbolMatchesTargetTypes(contextLookup, symbolList, typeConvertibilityCache, out var index);
                if (includeItemInTargetTypedCompletion && index > 0)
                {
                    // This would ensure a symbol matches target types to be used for description if there's any,
                    // assuming the default implementation of GetDescriptionWorkerAsync is used.
                    var firstMatch = symbolList[index];
                    symbolList = symbolList.RemoveAt(index);
                    symbolList = symbolList.Insert(0, firstMatch);
                }
            }

            var supportedPlatformData = ComputeSupportedPlatformData(completionContext, symbolList, invalidProjectMap, totalProjects);
            var item = CreateItem(
                completionContext, symbolGroup.Key.displayText, symbolGroup.Key.suffix, symbolGroup.Key.insertionText, symbolList, arbitraryFirstContext, supportedPlatformData);

            if (includeItemInTargetTypedCompletion)
            {
                item = item.AddTag(WellKnownTags.TargetTypeMatch);
            }

            itemListBuilder.Add(item);
        }

        return itemListBuilder.ToImmutableAndClear();
    }

    /// <summary>
    /// Alternative comparer to SymbolAndSelectionInfo's default which considers both the full symbol and preselect.
    /// </summary>
    private sealed class SymbolReferenceEquivalenceComparer : IEqualityComparer<SymbolAndSelectionInfo>
    {
        public static readonly SymbolReferenceEquivalenceComparer Instance = new();

        public bool Equals(SymbolAndSelectionInfo x, SymbolAndSelectionInfo y)
            => x.Symbol == y.Symbol && x.Preselect == y.Preselect;

Review comment (suggestion):
I know this code is preexisting, it is just odd to me to grab the first list item when we might reorder the list a few lines later. Perhaps a comment could be added explaining why the context is truly arbitrary.

Code after:

        using var _ = ArrayBuilder<CompletionItem>.GetInstance(out var itemListBuilder);
        var typeConvertibilityCache = new Dictionary<ITypeSymbol, bool>(SymbolEqualityComparer.Default);

        foreach (var symbolGroup in symbolGroups)
        {
            if (symbolGroup.Value.Count == 1)
            {
                // It's very rare to have multiple symbols with identical texts, 
                // so we optimize for single symbol case to minimize overhead.
                CreateAndAddItem([symbolGroup.Value.Single()], false);
            }
            else
            {
                var symbolLists = DeduplicateSymbols(symbolGroup.Value);
                var noMerge = symbolLists.Length > 1;
                foreach (var symbolList in symbolLists)
                {
                    CreateAndAddItem(symbolList, noMerge);
                }
            }

            void CreateAndAddItem(ImmutableArray<SymbolAndSelectionInfo> symbolList, bool doNotMerge)
            {
                var includeItemInTargetTypedCompletion = false;
                var arbitraryFirstContext = contextLookup(symbolList[0]);

                if (completionContext.CompletionOptions.TargetTypedCompletionFilter)
                {
                    includeItemInTargetTypedCompletion = TryFindFirstSymbolMatchesTargetTypes(contextLookup, symbolList, typeConvertibilityCache, out var index);
                    if (includeItemInTargetTypedCompletion && index > 0)
                    {
                        // This would ensure a symbol matches target types to be used for description if there's any,
                        // assuming the default implementation of GetDescriptionWorkerAsync is used.
                        var firstMatch = symbolList[index];
                        symbolList = symbolList.RemoveAt(index);
                        symbolList = symbolList.Insert(0, firstMatch);
                    }
                }

                var supportedPlatformData = ComputeSupportedPlatformData(completionContext, symbolList, invalidProjectMap, totalProjects);
                var item = CreateItem(
                    completionContext, symbolGroup.Key.displayText, symbolGroup.Key.suffix, symbolGroup.Key.insertionText, symbolList, arbitraryFirstContext, supportedPlatformData);

                if (includeItemInTargetTypedCompletion)
                {
                    item = item.AddTag(WellKnownTags.TargetTypeMatch);
                }

                if (doNotMerge)
                {