コード例 #1
0
        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());
コード例 #2
0
        private async Task <ImmutableDictionary <Project, ImmutableArray <Diagnostic> > > GetProjectDiagnosticsToFixAsync(IEnumerable <DiagnosticData> diagnosticsToFix, Func <Project, bool> shouldFixInProject, bool filterStaleDiagnostics, CancellationToken cancellationToken)
        {
            bool isProjectDiagnostic(DiagnosticData d) => d.DataLocation == null && d.ProjectId != null;

            var builder = ImmutableDictionary.CreateBuilder <ProjectId, List <DiagnosticData> >();

            foreach (var diagnosticData in diagnosticsToFix.Where(isProjectDiagnostic))
            {
                if (!builder.TryGetValue(diagnosticData.ProjectId, out var diagnosticsPerProject))
                {
                    diagnosticsPerProject             = new List <DiagnosticData>();
                    builder[diagnosticData.ProjectId] = diagnosticsPerProject;
                }

                diagnosticsPerProject.Add(diagnosticData);
            }

            if (builder.Count == 0)
            {
                return(ImmutableDictionary <Project, ImmutableArray <Diagnostic> > .Empty);
            }

            var finalBuilder = ImmutableDictionary.CreateBuilder <Project, ImmutableArray <Diagnostic> >();
            var latestDiagnosticsToFixOpt = filterStaleDiagnostics ? new HashSet <DiagnosticData>() : null;

            foreach (var kvp in builder)
            {
                var projectId = kvp.Key;
                var project   = _workspace.CurrentSolution.GetProject(projectId);
                if (project == null || !shouldFixInProject(project))
                {
                    continue;
                }

                var diagnostics = kvp.Value;
                IEnumerable <DiagnosticData> projectDiagnosticsToFix;
                if (filterStaleDiagnostics)
                {
                    var uniqueDiagnosticIds = diagnostics.Select(d => d.Id).ToImmutableHashSet();
                    var latestDiagnosticsFromDiagnosticService = (await _diagnosticService.GetDiagnosticsForIdsAsync(project.Solution, project.Id, diagnosticIds: uniqueDiagnosticIds, includeSuppressedDiagnostics: true, cancellationToken: cancellationToken)
                                                                  .ConfigureAwait(false));

                    latestDiagnosticsToFixOpt.Clear();
                    latestDiagnosticsToFixOpt.AddRange(latestDiagnosticsFromDiagnosticService.Where(isProjectDiagnostic));

                    // Filter out stale diagnostics in error list.
                    projectDiagnosticsToFix = diagnostics.Where(d => latestDiagnosticsFromDiagnosticService.Contains(d) || SuppressionHelpers.IsSynthesizedExternalSourceDiagnostic(d));
                }
                else
                {
                    projectDiagnosticsToFix = diagnostics;
                }

                if (projectDiagnosticsToFix.Any())
                {
                    var projectDiagnostics = await projectDiagnosticsToFix.ToDiagnosticsAsync(project, cancellationToken).ConfigureAwait(false);

                    finalBuilder.Add(project, projectDiagnostics);
                }
            }

            return(finalBuilder.ToImmutableDictionary());
        }