| File: Completion\MatchResult.cs | Web Access |
| Project: src\roslyn\src\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj (Microsoft.CodeAnalysis.Features) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Generic; using Microsoft.CodeAnalysis.PatternMatching; namespace Microsoft.CodeAnalysis.Completion; internal readonly struct MatchResult( CompletionItem completionItem, bool shouldBeConsideredMatchingFilterText, PatternMatch? patternMatch, int index, string? matchedAdditionalFilterText, int recentItemIndex = -1) { /// <summary> /// The CompletionItem used to create this MatchResult. /// </summary> public readonly CompletionItem CompletionItem = completionItem; public readonly PatternMatch? PatternMatch = patternMatch; // The value of `ShouldBeConsideredMatchingFilterText` doesn't 100% reflect the actual PatternMatch result. // In certain cases, there'd be no match but we'd still want to consider it a match (e.g. when the item is in MRU list,) // and this is why PatternMatch can be null. There's also cases it's a match but we want to consider it a non-match // (e.g. when not a prefix match in deletion scenario). public readonly bool ShouldBeConsideredMatchingFilterText = shouldBeConsideredMatchingFilterText; public string FilterTextUsed => MatchedAdditionalFilterText ?? CompletionItem.FilterText; // We want to preserve the original alphabetical order for items with same pattern match score, // but `ArrayBuilder.Sort` we currently use isn't stable. So we have to add a monotonically increasing // integer to achieve this. public readonly int IndexInOriginalSortedOrder = index; public readonly int RecentItemIndex = recentItemIndex; /// <summary> /// If `CompletionItem.AdditionalFilterTexts` was used to create this MatchResult, then this is set to the one that was used. /// Otherwise this is set to null. /// </summary> public readonly string? MatchedAdditionalFilterText = matchedAdditionalFilterText; public bool MatchedWithAdditionalFilterTexts => MatchedAdditionalFilterText is not null; public static IComparer<MatchResult> SortingComparer { get; } = new Comparer(); private sealed class Comparer : IComparer<MatchResult> { // This comparison is used for sorting items in the completion list for the original sorting. public int Compare(MatchResult x, MatchResult y) { var matchX = x.PatternMatch; var matchY = y.PatternMatch; if (matchX.HasValue) { if (matchY.HasValue) { var ret = matchX.Value.CompareTo(matchY.Value); // We'd rank match of FilterText over match of any of AdditionalFilterTexts if they has same pattern match score if (ret == 0) ret = x.MatchedWithAdditionalFilterTexts.CompareTo(y.MatchedWithAdditionalFilterTexts); // We want to preserve the original order for items with same pattern match score. return ret == 0 ? x.IndexInOriginalSortedOrder - y.IndexInOriginalSortedOrder : ret; } return -1; } if (matchY.HasValue) { return 1; } return x.IndexInOriginalSortedOrder - y.IndexInOriginalSortedOrder; } } public override string ToString() => this.CompletionItem.ToString(); }