/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/Core/Def/NavigateTo/RoslynNavigateToSearchCallback.cs
132 строки
7 KB
Cyrus Najmabadi
Fix SG items appearing in navto
10 дек 2025, 15:04
10 дек 2025, 15:04
1ab7f5f
Код
Авторство
О чём код?
// 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.Immutable; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text.Shared.Extensions; using Microsoft.VisualStudio.Search.Data; using Microsoft.VisualStudio.Text.PatternMatching; namespace Microsoft.CodeAnalysis.NavigateTo; internal sealed partial class RoslynSearchItemsSourceProvider { /// <summary> /// A callback to be passed to the <see cref="NavigateToSearcher"/>. Results it pushes into us will then be /// converted and pushed into <see cref="_searchCallback"/>. /// </summary> private sealed class RoslynNavigateToSearchCallback( Solution solution, RoslynSearchItemsSourceProvider provider, ISearchCallback searchCallback) : INavigateToSearchCallback { private readonly Solution _solution = solution; private readonly RoslynSearchItemsSourceProvider _provider = provider; private readonly ISearchCallback _searchCallback = searchCallback; public void Done(bool isFullyLoaded) { // Don't need to do anything here. The UI will naturally know we're complete as they are awaiting on // our search routine. } public void ReportProgress(int current, int maximum) => _searchCallback.ReportProgress(current, maximum); public void ReportIncomplete() { // IncompleteReason.Parsing corresponds to: // "The results may be inaccurate because the search information is still being updated." // // This the most accurate message for us as we only report this when we're currently reporting // potentially stale results from the nav-to cache. _searchCallback.ReportIncomplete(IncompleteReason.Parsing); } public async Task AddResultsAsync( ImmutableArray<INavigateToSearchResult> results, Document? activeDocument, CancellationToken cancellationToken) { // Convert roslyn pattern matches to the platform type. foreach (var result in results) { var matches = result.Matches.SelectAsArray(static m => new PatternMatch( ConvertKind(m.Kind), punctuationStripped: false, m.IsCaseSensitive, m.MatchedSpans.SelectAsArray(static s => s.ToSpan()))); // Weight the items based on the overall pattern matching weights. We want the items that have the best // pattern matches (low .Kind values) to have the highest float values (as higher is better for the VS // api). var perProviderItemPriority = float.MaxValue - Enumerable.Sum(result.Matches.Select(m => (int)m.Kind)); var project = _solution.GetRequiredProject(result.NavigableItem.Document.Project.Id); _searchCallback.AddItem(new RoslynCodeSearchResult( _provider, result, GetResultType(result.Kind), result.Name, result.SecondarySort, matches, await GetFilePathAsync(result).ConfigureAwait(false), perProviderItemPriority, project.Language, isActiveDocument: activeDocument != null && activeDocument.Id == result.NavigableItem.Document.Id)); } async ValueTask<string?> GetFilePathAsync(INavigateToSearchResult result) { var document = result.NavigableItem.Document; if (document.Id.IsSourceGenerated) { var foundDocument = await document.GetRequiredDocumentAsync(_solution, cancellationToken).ConfigureAwait(false); if (foundDocument is SourceGeneratedDocument sourceGeneratedDocument) return _provider._sourceGeneratedFileManager.MapSourceGeneratedDocumentToOpenableFilePath(sourceGeneratedDocument); } return document.FilePath; } } private static PatternMatchKind ConvertKind(PatternMatching.PatternMatchKind kind) => kind switch { PatternMatching.PatternMatchKind.Exact => PatternMatchKind.Exact, PatternMatching.PatternMatchKind.Prefix => PatternMatchKind.Prefix, PatternMatching.PatternMatchKind.NonLowercaseSubstring => PatternMatchKind.Substring, PatternMatching.PatternMatchKind.StartOfWordSubstring => PatternMatchKind.Substring, PatternMatching.PatternMatchKind.CamelCaseExact => PatternMatchKind.CamelCaseExact, PatternMatching.PatternMatchKind.CamelCasePrefix => PatternMatchKind.CamelCasePrefix, PatternMatching.PatternMatchKind.CamelCaseNonContiguousPrefix => PatternMatchKind.CamelCaseNonContiguousPrefix, PatternMatching.PatternMatchKind.CamelCaseSubstring => PatternMatchKind.CamelCaseSubstring, PatternMatching.PatternMatchKind.CamelCaseNonContiguousSubstring => PatternMatchKind.CamelCaseNonContiguousSubstring, PatternMatching.PatternMatchKind.Fuzzy => PatternMatchKind.Fuzzy, // Map our value to 'Fuzzy' as that's the lower value the platform supports. PatternMatching.PatternMatchKind.LowercaseSubstring => PatternMatchKind.Fuzzy, _ => PatternMatchKind.Fuzzy, }; private static string GetResultType(string kind) => kind switch { NavigateToItemKind.Class => CodeSearchResultType.Class, NavigateToItemKind.Constant => CodeSearchResultType.Constant, NavigateToItemKind.Delegate => CodeSearchResultType.Delegate, NavigateToItemKind.Enum => CodeSearchResultType.Enum, NavigateToItemKind.EnumItem => CodeSearchResultType.EnumItem, NavigateToItemKind.Event => CodeSearchResultType.Event, NavigateToItemKind.Field => CodeSearchResultType.Field, NavigateToItemKind.Interface => CodeSearchResultType.Interface, NavigateToItemKind.Method => CodeSearchResultType.Method, NavigateToItemKind.Module => CodeSearchResultType.Module, NavigateToItemKind.OtherSymbol => CodeSearchResultType.OtherSymbol, NavigateToItemKind.Property => CodeSearchResultType.Property, NavigateToItemKind.Structure => CodeSearchResultType.Structure, _ => kind }; } }