private async Task SearchCurrentDocumentAsync(CancellationToken cancellationToken)
        {
            if (_activeDocument == null)
            {
                return;
            }

            var project = _activeDocument.Project;
            var service = _host.GetNavigateToSearchService(project);

            if (service == null)
            {
                return;
            }

            await _progress.AddItemsAsync(1, cancellationToken).ConfigureAwait(false);

            try
            {
                await service.SearchDocumentAsync(
                    _activeDocument, _searchPattern, _kinds,
                    r => _callback.AddItemAsync(project, r, cancellationToken),
                    cancellationToken).ConfigureAwait(false);
            }
            finally
            {
                await _progress.ItemCompletedAsync(cancellationToken).ConfigureAwait(false);
            }
        }
        public async Task FindReferencesAsync(SymbolAndProjectId symbolAndProjectId)
        {
            await _progress.OnStartedAsync().ConfigureAwait(false);

            await _progressTracker.AddItemsAsync(1).ConfigureAwait(false);

            try
            {
                var symbols = await DetermineAllSymbolsAsync(symbolAndProjectId).ConfigureAwait(false);

                var projectMap = await CreateProjectMapAsync(symbols).ConfigureAwait(false);

                var projectToDocumentMap = await CreateProjectToDocumentMapAsync(projectMap).ConfigureAwait(false);

                ValidateProjectToDocumentMap(projectToDocumentMap);

                await ProcessAsync(projectToDocumentMap).ConfigureAwait(false);
            }
            finally
            {
                await _progressTracker.ItemCompletedAsync().ConfigureAwait(false);

                await _progress.OnCompletedAsync().ConfigureAwait(false);
            }
        }
        private async Task ProcessAsync(ProjectToDocumentMap projectToDocumentMap)
        {
            using (Logger.LogBlock(FunctionId.FindReference_ProcessAsync, _cancellationToken))
            {
                // quick exit
                if (projectToDocumentMap.Count == 0)
                {
                    return;
                }

                // Add a progress item for each (document, symbol, finder) set that we will execute.
                // We'll mark the item as completed in "ProcessDocumentAsync".
                var totalFindCount = projectToDocumentMap.Sum(
                    kvp1 => kvp1.Value.Sum(kvp2 => kvp2.Value.Count));
                await _progressTracker.AddItemsAsync(totalFindCount).ConfigureAwait(false);

                using var _ = ArrayBuilder <Task> .GetInstance(out var tasks);

                foreach (var(project, documentMap) in projectToDocumentMap)
                {
                    tasks.Add(Task.Factory.StartNew(() => ProcessProjectAsync(project, documentMap), _cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap());
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);
            }
        }
Exemple #4
0
 private async Task AddProgressItemsAsync(int count, CancellationToken cancellationToken)
 {
     Debug.Assert(count >= 0);
     Debug.Assert(_remainingProgressItems >= 0);
     Interlocked.Add(ref _remainingProgressItems, count);
     await _progress_doNotAccessDirectly.AddItemsAsync(count, cancellationToken).ConfigureAwait(false);
 }
        public async Task FindReferencesAsync()
        {
            await _progressTracker.AddItemsAsync(1).ConfigureAwait(false);

            try
            {
                if (_searchKind != SearchKind.None)
                {
                    await FindReferencesWorkerAsync().ConfigureAwait(false);
                }
            }
            finally
            {
                await _progressTracker.ItemCompletedAsync().ConfigureAwait(false);
            }
        }
        public static async Task <IAsyncDisposable> AddSingleItemAsync(
            this IStreamingProgressTracker progressTracker
            )
        {
            await progressTracker.AddItemsAsync(1).ConfigureAwait(false);

            return(new StreamingProgressDisposer(progressTracker));
        }
Exemple #7
0
        private async Task <(int itemsReported, ImmutableArray <(Project project, NavigateToSearchLocation location)>)> ProcessProjectsAsync(
            ImmutableArray <ImmutableArray <Project> > orderedProjects, bool isFullyLoaded, CancellationToken cancellationToken)
        {
            await _progress.AddItemsAsync(orderedProjects.Sum(p => p.Length), cancellationToken).ConfigureAwait(false);

            using var _ = ArrayBuilder <(Project project, NavigateToSearchLocation location)> .GetInstance(out var result);

            var seenItems = new HashSet <INavigateToSearchResult>(NavigateToSearchResultComparer.Instance);

            foreach (var projectGroup in orderedProjects)
            {
                result.AddRange(await Task.WhenAll(projectGroup.Select(p => Task.Run(() => SearchAsync(p, isFullyLoaded, seenItems, cancellationToken)))).ConfigureAwait(false));
            }

            return(seenItems.Count, result.ToImmutable());
        }
        private async Task FindReferencesWorkerAsync()
        {
            var count = _solution.Projects.SelectMany(p => p.DocumentIds).Count();
            await _progressTracker.AddItemsAsync(count).ConfigureAwait(false);

            foreach (var project in _solution.Projects)
            {
                _cancellationToken.ThrowIfCancellationRequested();

                var documentTasks = new List <Task>();
                foreach (var document in project.Documents)
                {
                    documentTasks.Add(ProcessDocumentAsync(document));
                }

                await Task.WhenAll(documentTasks).ConfigureAwait(false);
            }
        }
        private async Task ProcessAsync(ProjectToDocumentMap projectToDocumentMap)
        {
            using (Logger.LogBlock(FunctionId.FindReference_ProcessAsync, _cancellationToken))
            {
                // quick exit
                if (projectToDocumentMap.Count == 0)
                {
                    return;
                }

                // Get the connected components of the dependency graph and process each individually.
                // That way once a component is done we can throw away all the memory associated with
                // it.
                // For each connected component, we'll process the individual projects from bottom to
                // top.  i.e. we'll first process the projects with no dependencies.  Then the projects
                // that depend on those projects, and so on.  This way we always have created the
                // dependent compilations when they're needed by later projects.  If we went the other
                // way (i.e. processed the projects with lots of project dependencies first), then we'd
                // have to create all their dependent compilations in order to get their compilation.
                // This would be very expensive and would take a lot of time before we got our first
                // result.
                var connectedProjects = _dependencyGraph.GetDependencySets(_cancellationToken);

                // Add a progress item for each (document, symbol, finder) set that we will execute.
                // We'll mark the item as completed in "ProcessDocumentAsync".
                var totalFindCount = projectToDocumentMap.Sum(
                    kvp1 => kvp1.Value.Sum(kvp2 => kvp2.Value.Count));
                await _progressTracker.AddItemsAsync(totalFindCount).ConfigureAwait(false);

                // Now, go through each connected project set and process it independently.
                foreach (var connectedProjectSet in connectedProjects)
                {
                    _cancellationToken.ThrowIfCancellationRequested();

                    await ProcessProjectsAsync(
                        connectedProjectSet, projectToDocumentMap).ConfigureAwait(false);
                }
            }
        }
        internal async Task SearchAsync()
        {
            var isFullyLoaded = true;

            try
            {
                var service = _solution.Workspace.Services.GetRequiredService <IWorkspaceStatusService>();
                isFullyLoaded = await service.IsFullyLoadedAsync(_cancellationToken).ConfigureAwait(false);

                using var navigateToSearch = Logger.LogBlock(FunctionId.NavigateTo_Search, KeyValueLogMessage.Create(LogType.UserAction), _cancellationToken);
                using var asyncToken       = _asyncListener.BeginAsyncOperation(GetType() + ".Search");
                await _progress.AddItemsAsync(_solution.Projects.Count()).ConfigureAwait(false);
                await SearchAllProjectsAsync().ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
            }
            finally
            {
                // providing this extra information will make UI to show indication to users
                // that result might not contain full data
                _callback.Done(isFullyLoaded);
            }
        }
 public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken)
 => _progressTracker.AddItemsAsync(count, cancellationToken);