public ActiveProjectCacheManager(IDocumentTrackingService documentTrackingService, ProjectCacheService projectCacheService)
            {
                _documentTrackingService = documentTrackingService;
                _projectCacheService     = projectCacheService;

                if (documentTrackingService != null)
                {
                    documentTrackingService.ActiveDocumentChanged += UpdateCache;
                    UpdateCache(null, documentTrackingService.GetActiveDocument());
                }
            }
Example #2
0
            public WorkCoordinator(
                IAsynchronousOperationListener listener,
                IEnumerable <Lazy <IIncrementalAnalyzerProvider, IncrementalAnalyzerProviderMetadata> > analyzerProviders,
                bool initializeLazily,
                Registration registration)
            {
                _logAggregator = new LogAggregator();

                _registration = registration;
                _gate         = new object();

                _listener                = listener;
                _optionService           = _registration.GetService <IOptionService>();
                _documentTrackingService = _registration.GetService <IDocumentTrackingService>();

                // event and worker queues
                _shutdownNotificationSource = new CancellationTokenSource();
                _shutdownToken = _shutdownNotificationSource.Token;

                _eventProcessingQueue = new TaskQueue(listener, TaskScheduler.Default);

                var activeFileBackOffTimeSpanInMS          = _optionService.GetOption(InternalSolutionCrawlerOptions.ActiveFileWorkerBackOffTimeSpanInMS);
                var allFilesWorkerBackOffTimeSpanInMS      = _optionService.GetOption(InternalSolutionCrawlerOptions.AllFilesWorkerBackOffTimeSpanInMS);
                var entireProjectWorkerBackOffTimeSpanInMS = _optionService.GetOption(InternalSolutionCrawlerOptions.EntireProjectWorkerBackOffTimeSpanInMS);

                _documentAndProjectWorkerProcessor = new IncrementalAnalyzerProcessor(
                    listener, analyzerProviders, initializeLazily, _registration,
                    activeFileBackOffTimeSpanInMS, allFilesWorkerBackOffTimeSpanInMS, entireProjectWorkerBackOffTimeSpanInMS, _shutdownToken);

                var semanticBackOffTimeSpanInMS = _optionService.GetOption(InternalSolutionCrawlerOptions.SemanticChangeBackOffTimeSpanInMS);
                var projectBackOffTimeSpanInMS  = _optionService.GetOption(InternalSolutionCrawlerOptions.ProjectPropagationBackOffTimeSpanInMS);

                _semanticChangeProcessor = new SemanticChangeProcessor(listener, _registration, _documentAndProjectWorkerProcessor, semanticBackOffTimeSpanInMS, projectBackOffTimeSpanInMS, _shutdownToken);

                // if option is on
                if (_optionService.GetOption(InternalSolutionCrawlerOptions.SolutionCrawler))
                {
                    _registration.Workspace.WorkspaceChanged += OnWorkspaceChanged;
                    _registration.Workspace.DocumentOpened   += OnDocumentOpened;
                    _registration.Workspace.DocumentClosed   += OnDocumentClosed;
                }

                // subscribe to option changed event after all required fields are set
                // otherwise, we can get null exception when running OnOptionChanged handler
                _optionService.OptionChanged += OnOptionChanged;

                // subscribe to active document changed event for active file background analysis scope.
                if (_documentTrackingService != null)
                {
                    _lastActiveDocument = _documentTrackingService.GetActiveDocument(_registration.Workspace.CurrentSolution);
                    _documentTrackingService.ActiveDocumentChanged += OnActiveDocumentChanged;
                }
            }
Example #3
0
            private async Task SearchProjectsInPriorityOrder(IDocumentTrackingService docTrackingService)
            {
                var processedProjects = new HashSet <Project>();

                var activeDocOpt = docTrackingService.GetActiveDocument(_solution);
                var visibleDocs  = docTrackingService.GetVisibleDocuments(_solution)
                                   .Where(d => d != activeDocOpt)
                                   .ToImmutableArray();

                // First, if there's an active document, search that project first, prioritizing
                // that active document and all visible documents from it.
                if (activeDocOpt != null)
                {
                    var activeProject = activeDocOpt.Project;
                    processedProjects.Add(activeProject);

                    var visibleDocsFromProject = visibleDocs.Where(d => d.Project == activeProject);
                    var priorityDocs           = ImmutableArray.Create(activeDocOpt).AddRange(visibleDocsFromProject);

                    // Search the active project first.  That way we can deliver results that are
                    // closer in scope to the user quicker without forcing them to do something like
                    // NavToInCurrentDoc
                    await Task.Run(() => SearchAsync(activeProject, priorityDocs), _cancellationToken).ConfigureAwait(false);
                }

                // Now, process all visible docs that were not from the active project.
                var tasks = new List <Task>();

                foreach (var(currentProject, priorityDocs) in visibleDocs.GroupBy(d => d.Project))
                {
                    // make sure we only process this project if we didn't already process it above.
                    if (processedProjects.Add(currentProject))
                    {
                        tasks.Add(Task.Run(() => SearchAsync(currentProject, priorityDocs.ToImmutableArray()), _cancellationToken));
                    }
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);

                // Now, process the remainder of projects
                tasks.Clear();
                foreach (var currentProject in _solution.Projects)
                {
                    // make sure we only process this project if we didn't already process it above.
                    if (processedProjects.Add(currentProject))
                    {
                        tasks.Add(Task.Run(() => SearchAsync(currentProject, ImmutableArray <Document> .Empty), _cancellationToken));
                    }
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);
            }
                internal ProjectId GetActiveProject()
                {
                    ProjectId activeProjectId = null;

                    if (_documentTracker != null)
                    {
                        var activeDocument = _documentTracker.GetActiveDocument();
                        if (activeDocument != null)
                        {
                            activeProjectId = activeDocument.ProjectId;
                        }
                    }

                    return(null);
                }
Example #5
0
 public DocumentId GetActiveDocument()
 {
     return(_inner.GetActiveDocument());
 }
            public ActiveProjectCacheManager(IDocumentTrackingService documentTrackingService, ProjectCacheService projectCacheService)
            {
                _documentTrackingService = documentTrackingService;
                _projectCacheService = projectCacheService;

                if (documentTrackingService != null)
                {
                    documentTrackingService.ActiveDocumentChanged += UpdateCache;
                    UpdateCache(null, documentTrackingService.GetActiveDocument());
                }
            }
        private bool TryGetNextBestItemToReport_NoLock(out ValueTuple <object, VisualStudioTaskItem[]> bestItemToReport)
        {
            bestItemToReport = default(ValueTuple <object, VisualStudioTaskItem[]>);

            // no item to report
            if (!this.HasPendingTaskItemsToReport)
            {
                return(false);
            }

            // order of process is like this
            // 1. active document
            var activeDocumentId = _documentTracker.GetActiveDocument();

            if (activeDocumentId != null &&
                TryGetNextBestItemToReport_NoLock(_notReportedDocumentItemMap, activeDocumentId, out bestItemToReport))
            {
                return(true);
            }

            // 2. visible documents
            foreach (var visibleDocumentId in _documentTracker.GetVisibleDocuments())
            {
                if (TryGetNextBestItemToReport_NoLock(_notReportedDocumentItemMap, visibleDocumentId, out bestItemToReport))
                {
                    return(true);
                }
            }

            // 3. opened documents
            if (TryGetNextBestItemToReportFromOpenedFiles_NoLock(out bestItemToReport))
            {
                return(true);
            }

            if (!this.IsUnderThreshold)
            {
                return(false);
            }

            // 4. documents in the project where active document is in
            if (activeDocumentId != null)
            {
                if (TryGetNextBestItemToReport_NoLock(
                        _notReportedDocumentItemMap, keys => keys.FirstOrDefault(k => k.ProjectId == activeDocumentId.ProjectId),
                        (s, k) => s.ContainsDocument(k), out bestItemToReport))
                {
                    return(true);
                }
            }

            // just take random one from the document map
            if (_notReportedDocumentItemMap.Count > 0)
            {
                if (TryGetNextBestItemToReport_NoLock(_notReportedDocumentItemMap, keys => keys.FirstOrDefault(), (s, k) => s.ContainsDocument(k), out bestItemToReport))
                {
                    return(true);
                }
            }

            if (_notReportedProjectItemsMap.Count > 0)
            {
                if (TryGetNextBestItemToReport_NoLock(_notReportedProjectItemsMap, keys => keys.FirstOrDefault(), (s, k) => s.ContainsProject(k), out bestItemToReport))
                {
                    return(true);
                }
            }

            return(false);
        }
 /// <summary>
 /// Gets the active <see cref="Document"/> the user is currently working in. May be null if
 /// there is no active document or the active document is not in this <paramref name="solution"/>.
 /// </summary>
 public static Document GetActiveDocument(this IDocumentTrackingService service, Solution solution)
 {
     // Note: GetDocument checks that the DocId is contained in the solution, and returns null if not.
     return(solution.GetDocument(service.GetActiveDocument()));
 }