private DocumentId GetBestDocumentId_NoLock( ProjectId?preferableProjectId, ProjectDependencyGraph dependencyGraph, IDiagnosticAnalyzerService?analyzerService ) { var projectId = GetBestProjectId_NoLock( _documentWorkQueue, preferableProjectId, dependencyGraph, analyzerService ); var documentMap = _documentWorkQueue[projectId]; // explicitly iterate so that we can use struct enumerator. // Return the first normal priority work item we find. If we don't // find any, then just return the first low prio item we saw. DocumentId?lowPriorityDocumentId = null; foreach (var(documentId, workItem) in documentMap) { if (workItem.IsLowPriority) { lowPriorityDocumentId = documentId; } else { return(documentId); } } Contract.ThrowIfNull(lowPriorityDocumentId); return(lowPriorityDocumentId); }
private static bool CheckTelemetry(DiagnosticAnalyzer analyzer, IDiagnosticAnalyzerService?analyzerService) { if (analyzer.IsCompilerAnalyzer()) { return(true); } if (analyzer is IBuiltInAnalyzer) { // if it is builtin analyzer, telemetry is always allowed return(true); } ImmutableArray <DiagnosticDescriptor> diagDescriptors; try { // SupportedDiagnostics is potentially user code and can throw an exception. diagDescriptors = analyzerService != null?analyzerService.GetDiagnosticDescriptors(analyzer) : analyzer.SupportedDiagnostics; } catch (Exception) { return(false); } if (diagDescriptors == null) { return(false); } // find if the first diagnostic in this analyzer allows telemetry var diagnostic = diagDescriptors.Length > 0 ? diagDescriptors[0] : null; return(diagnostic == null ? false : diagnostic.CustomTags.Any(t => t == WellKnownDiagnosticTags.Telemetry)); }
protected override bool TryTakeAnyWork_NoLock( ProjectId?preferableProjectId, ProjectDependencyGraph dependencyGraph, IDiagnosticAnalyzerService?service, out WorkItem workItem ) { // there must be at least one item in the map when this is called unless host is shutting down. if (_documentWorkQueue.Count == 0) { workItem = default; return(false); } var documentId = GetBestDocumentId_NoLock( preferableProjectId, dependencyGraph, service ); if (TryTake_NoLock(documentId, out workItem)) { return(true); } throw ExceptionUtilities.Unreachable; }
public bool TryTakeAnyWork( ProjectId?preferableProjectId, ProjectDependencyGraph dependencyGraph, IDiagnosticAnalyzerService?analyzerService, out WorkItem workItem, out CancellationToken cancellationToken ) { lock (_gate) { // there must be at least one item in the map when this is called unless host is shutting down. if ( TryTakeAnyWork_NoLock( preferableProjectId, dependencyGraph, analyzerService, out workItem ) ) { cancellationToken = GetNewCancellationToken_NoLock(workItem.Key); workItem.AsyncToken.Dispose(); return(true); } else { cancellationToken = CancellationToken.None; return(false); } } }
public static bool AllowsTelemetry(DiagnosticAnalyzer analyzer, IDiagnosticAnalyzerService?analyzerService = null) { if (s_telemetryCache.TryGetValue(analyzer, out var value)) { return(value.Value); } return(s_telemetryCache.GetValue(analyzer, a => new StrongBox <bool>(CheckTelemetry(a, analyzerService))).Value); }
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; }
protected abstract bool TryTakeAnyWork_NoLock(ProjectId?preferableProjectId, ProjectDependencyGraph dependencyGraph, IDiagnosticAnalyzerService?service, out WorkItem workItem);