private ProjectId GetBestProjectId_NoLock(ProjectId projectId, ProjectDependencyGraph dependencyGraph) { if (projectId != null) { if (_documentWorkQueue.ContainsKey(projectId)) { return(projectId); } // see if there is any project that depends on this project has work item queued. if there is any, use that project // as next project to process foreach (var dependingProjectId in dependencyGraph.GetProjectsThatDirectlyDependOnThisProject(projectId)) { if (_documentWorkQueue.ContainsKey(dependingProjectId)) { return(dependingProjectId); } } } // explicitly iterate so that we can use struct enumerator foreach (var pair in _documentWorkQueue) { return(pair.Key); } return(Contract.FailWithReturn <ProjectId>("Shouldn't reach here")); }
protected override bool TryTakeAnyWork_NoLock(ProjectId preferableProjectId, ProjectDependencyGraph dependencyGraph, out WorkItem workItem) { if (preferableProjectId != null) { if (TryTake_NoLock(preferableProjectId, out workItem)) { return(true); } foreach (var dependingProjectId in dependencyGraph.GetProjectsThatDirectlyDependOnThisProject(preferableProjectId)) { if (TryTake_NoLock(dependingProjectId, out workItem)) { return(true); } } } // explicitly iterate so that we can use struct enumerator foreach (var kvp in _projectWorkQueue) { workItem = kvp.Value; return(_projectWorkQueue.Remove(kvp.Key)); } workItem = default(WorkItem); return(false); }
private void FindDependentProjectsRecursively(ProjectDependencyGraph graph, Dictionary <ProjectId, AnalysisResult> results, int distance) { if (distance > _distanceHardLimit) { throw new InvalidOperationException($"Project recursion depth exceeded hard limit of {_distanceHardLimit}"); } ++distance; int startingProjectCount = results.Values.Count; var ancestors = results.Values.Where(r => r.Distance == distance - 1).ToList(); foreach (var project in ancestors) { var projectObj = _loader.Solution.Projects.SingleOrDefault(p => p.FilePath.Equals(project.FilePath, StringComparison.OrdinalIgnoreCase)); var dependentProjectIds = graph.GetProjectsThatDirectlyDependOnThisProject(projectObj.Id); var newDependentProjectIds = dependentProjectIds.Where(id => !results.ContainsKey(id)); var newDependentProjects = _loader.Solution.Projects.Where(p => newDependentProjectIds.Contains(p.Id)); foreach (var newProject in newDependentProjects) { results.Add(newProject.Id, CreateAnalysisResult(newProject, distance)); } } // As long as we keep finding projects, keep searching. if (startingProjectCount < results.Values.Count) { FindDependentProjectsRecursively(graph, results, distance); } }
protected ProjectId GetBestProjectId_NoLock <T>( Dictionary <ProjectId, T> workQueue, ProjectId?projectId, ProjectDependencyGraph dependencyGraph, IDiagnosticAnalyzerService?analyzerService ) { if (projectId != null) { if (workQueue.ContainsKey(projectId)) { return(projectId); } // prefer project that directly depends on the given project and has diagnostics as next project to // process foreach ( var dependingProjectId in dependencyGraph.GetProjectsThatDirectlyDependOnThisProject( projectId ) ) { if ( workQueue.ContainsKey(dependingProjectId) && analyzerService?.ContainsDiagnostics( Workspace, dependingProjectId ) == true ) { return(dependingProjectId); } } } // prefer a project that has diagnostics as next project to process. foreach (var pendingProjectId in workQueue.Keys) { if ( analyzerService?.ContainsDiagnostics(Workspace, pendingProjectId) == true ) { return(pendingProjectId); } } // explicitly iterate so that we can use struct enumerator foreach (var pair in workQueue) { return(pair.Key); } throw ExceptionUtilities.Unreachable; }