private async Task <IEnumerable <Diagnostic> > GetDocumentDiagnosticsAsync(Document document, ImmutableHashSet <string> diagnosticIds, CancellationToken cancellationToken) { Contract.ThrowIfNull(document); var solution = document.Project.Solution; var diagnostics = await _diagnosticService.GetDiagnosticsForIdsAsync(solution, null, document.Id, diagnosticIds, cancellationToken : cancellationToken).ConfigureAwait(false); Contract.ThrowIfFalse(diagnostics.All(d => d.DocumentId != null)); return(await diagnostics.ToDiagnosticsAsync(document.Project, cancellationToken).ConfigureAwait(false)); }
private async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixAsync(IEnumerable <DiagnosticData> diagnosticsToFix, Func <Project, bool> shouldFixInProject, bool filterStaleDiagnostics, CancellationToken cancellationToken) { var builder = ImmutableDictionary.CreateBuilder <DocumentId, List <DiagnosticData> >(); foreach (var diagnosticData in diagnosticsToFix.Where(IsDocumentDiagnostic)) { RoslynDebug.AssertNotNull(diagnosticData.DocumentId); if (!builder.TryGetValue(diagnosticData.DocumentId, out var diagnosticsPerDocument)) { diagnosticsPerDocument = new List <DiagnosticData>(); builder[diagnosticData.DocumentId] = diagnosticsPerDocument; } diagnosticsPerDocument.Add(diagnosticData); } if (builder.Count == 0) { return(ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Empty); } var finalBuilder = ImmutableDictionary.CreateBuilder <Document, ImmutableArray <Diagnostic> >(); var latestDocumentDiagnosticsMap = filterStaleDiagnostics ? new Dictionary <DocumentId, ImmutableHashSet <DiagnosticData> >() : null; foreach (var group in builder.GroupBy(kvp => kvp.Key.ProjectId)) { var projectId = group.Key; var project = _workspace.CurrentSolution.GetProject(projectId); if (project == null || !shouldFixInProject(project)) { continue; } if (filterStaleDiagnostics) { RoslynDebug.AssertNotNull(latestDocumentDiagnosticsMap); var uniqueDiagnosticIds = group.SelectMany(kvp => kvp.Value.Select(d => d.Id)).ToImmutableHashSet(); var latestProjectDiagnostics = (await _diagnosticService.GetDiagnosticsForIdsAsync(project.Solution, project.Id, diagnosticIds: uniqueDiagnosticIds, includeSuppressedDiagnostics: true, cancellationToken: cancellationToken) .ConfigureAwait(false)).Where(IsDocumentDiagnostic); latestDocumentDiagnosticsMap.Clear(); foreach (var kvp in latestProjectDiagnostics.Where(d => d.DocumentId != null).GroupBy(d => d.DocumentId !)) { latestDocumentDiagnosticsMap.Add(kvp.Key, kvp.ToImmutableHashSet()); } } foreach (var documentDiagnostics in group) { var document = project.GetDocument(documentDiagnostics.Key); if (document == null) { continue; } IEnumerable <DiagnosticData> documentDiagnosticsToFix; if (filterStaleDiagnostics) { RoslynDebug.AssertNotNull(latestDocumentDiagnosticsMap); if (!latestDocumentDiagnosticsMap.TryGetValue(document.Id, out var latestDocumentDiagnostics)) { // Ignore stale diagnostics in error list. latestDocumentDiagnostics = ImmutableHashSet <DiagnosticData> .Empty; } // Filter out stale diagnostics in error list. documentDiagnosticsToFix = documentDiagnostics.Value.Where(d => latestDocumentDiagnostics.Contains(d) || SuppressionHelpers.IsSynthesizedExternalSourceDiagnostic(d)); } else { documentDiagnosticsToFix = documentDiagnostics.Value; } if (documentDiagnosticsToFix.Any()) { var diagnostics = await documentDiagnosticsToFix.ToDiagnosticsAsync(project, cancellationToken).ConfigureAwait(false); finalBuilder.Add(document, diagnostics); } } } return(finalBuilder.ToImmutableDictionary());