public ActiveProjectCacheManager(IDocumentTrackingService documentTrackingService, ProjectCacheService projectCacheService) { _documentTrackingService = documentTrackingService; _projectCacheService = projectCacheService; if (documentTrackingService != null) { documentTrackingService.ActiveDocumentChanged += UpdateCache; UpdateCache(null, documentTrackingService.GetActiveDocument()); } }
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; } }
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); }
public DocumentId GetActiveDocument() { return(_inner.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())); }