File: Progression\GraphQueries\SearchGraphQuery.cs
Web Access
Project: src\src\VisualStudio\Core\Def\Microsoft.VisualStudio.LanguageServices_pxr0p0dn_wpftmp.csproj (Microsoft.VisualStudio.LanguageServices)
// 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.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.NavigateTo;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.VisualStudio.GraphModel;
 
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression;
 
internal sealed partial class SearchGraphQuery(
    string searchPattern,
    NavigateToDocumentSupport searchScope) : IGraphQuery
{
    public async Task<GraphBuilder> GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken)
    {
        var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false);
        var callback = new ProgressionNavigateToSearchCallback(solution, context, graphBuilder);
 
        // We have a specialized host for progression vs normal nav-to.  Progression itself will tell the client if
        // the project is fully loaded or not.  But after that point, the client will be considered fully loaded and
        // results should reflect that.  So we create a host here that will always give complete results once the
        // solution is loaded and not give cached/incomplete results at that point.
        var statusService = solution.Services.GetRequiredService<IWorkspaceStatusService>();
        var isFullyLoaded = await statusService.IsFullyLoadedAsync(cancellationToken).ConfigureAwait(false);
        var host = new SearchGraphQueryNavigateToSearchHost(isFullyLoaded);
 
        var searcher = NavigateToSearcher.Create(
            solution,
            callback,
            searchPattern,
            NavigateToUtilities.GetKindsProvided(solution),
            host);
 
        await searcher.SearchAsync(NavigateToSearchScope.Solution, searchScope, cancellationToken).ConfigureAwait(false);
 
        return graphBuilder;
    }
 
    private sealed class SearchGraphQueryNavigateToSearchHost(bool isFullyLoaded) : INavigateToSearcherHost
    {
        public INavigateToSearchService? GetNavigateToSearchService(Project project)
            => project.GetLanguageService<INavigateToSearchService>();
 
        public ValueTask<bool> IsFullyLoadedAsync(CancellationToken cancellationToken)
            => new(isFullyLoaded);
    }
}