/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/LanguageServer/Protocol/Handler/Symbols/WorkspaceSymbolsHandler.cs
123 строки
5 KB
Cyrus Najmabadi
Simplify
17 июн 2025, 04:12
17 июн 2025, 04:12
a3aed10
Код
Авторство
О чём код?
// 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; using System.Collections.Immutable; using System.Composition; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.NavigateTo; using Microsoft.CodeAnalysis.Shared.TestHooks; using Roslyn.LanguageServer.Protocol; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.LanguageServer.Handler; /// <summary> /// TODO - This must be moved to the MS.CA.LanguageServer.Protocol project once /// we no longer reference VS icon types. /// </summary> [ExportCSharpVisualBasicStatelessLspService(typeof(WorkspaceSymbolsHandler)), Shared] [Method(Methods.WorkspaceSymbolName)] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] internal sealed class WorkspaceSymbolsHandler(IAsynchronousOperationListenerProvider listenerProvider) : ILspServiceRequestHandler<WorkspaceSymbolParams, SumType<SymbolInformation[], WorkspaceSymbol[]>?> { private static readonly IImmutableSet<string> s_supportedKinds = [ NavigateToItemKind.Class, NavigateToItemKind.Constant, NavigateToItemKind.Delegate, NavigateToItemKind.Enum, NavigateToItemKind.EnumItem, NavigateToItemKind.Event, NavigateToItemKind.Field, NavigateToItemKind.Interface, NavigateToItemKind.Method, NavigateToItemKind.Module, NavigateToItemKind.Property, NavigateToItemKind.Structure ]; private readonly IAsynchronousOperationListener _asyncListener = listenerProvider.GetListener(FeatureAttribute.NavigateTo); public bool MutatesSolutionState => false; public bool RequiresLSPSolution => true; public async Task<SumType<SymbolInformation[], WorkspaceSymbol[]>?> HandleRequestAsync(WorkspaceSymbolParams request, RequestContext context, CancellationToken cancellationToken) { Contract.ThrowIfNull(context.Solution); var solution = context.Solution; using var progress = BufferedProgress.Create( request.PartialResultToken, (SymbolInformation[] t) => new SumType<SymbolInformation[], WorkspaceSymbol[]>(t)); var searcher = NavigateToSearcher.Create( solution, _asyncListener, new LSPNavigateToCallback(context, progress), request.Query, s_supportedKinds, cancellationToken); await searcher.SearchAsync(NavigateToSearchScope.Solution, cancellationToken).ConfigureAwait(false); return progress.GetValues()?.Flatten().ToArray(); } private sealed class LSPNavigateToCallback( RequestContext context, BufferedProgress<SymbolInformation[]> progress) : INavigateToSearchCallback { public async Task AddResultsAsync( ImmutableArray<INavigateToSearchResult> results, Document? activeDocument, CancellationToken cancellationToken) { Contract.ThrowIfNull(context.Solution); var solution = context.Solution; var clientCapabilities = context.GetRequiredClientCapabilities(); var supportsVSExtensions = clientCapabilities.HasVisualStudioLspCapability(); foreach (var result in results) { var document = await result.NavigableItem.Document.GetRequiredDocumentAsync(solution, cancellationToken).ConfigureAwait(false); var location = await ProtocolConversions.TextSpanToLocationAsync( document, result.NavigableItem.SourceSpan, result.NavigableItem.IsStale, context, cancellationToken).ConfigureAwait(false); if (location == null) return; var symbolInfo = SymbolInformationFactory.Create( result.Name, result.AdditionalInformation, ProtocolConversions.NavigateToKindToSymbolKind(result.Kind), location, result.NavigableItem.Glyph, supportsVSExtensions); progress.Report(symbolInfo); } } public void Done(bool isFullyLoaded) { // do nothing, we already await the SearchAsync method which calls this in a finally right before returning. // used by non-LSP editor API. } public void ReportProgress(int current, int maximum) { // do nothing, LSP doesn't support reporting progress towards completion. // used by non-LSP editor API. } public void ReportIncomplete() { } } }