File: src\libraries\System.Runtime.InteropServices\gen\Common\FixAllContextExtensions.cs
Web Access
Project: src\src\libraries\System.Runtime.InteropServices\gen\ComInterfaceGenerator\ComInterfaceGenerator.csproj (Microsoft.Interop.ComInterfaceGenerator)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
 
namespace Microsoft.Interop.Analyzers
{
    internal static class FixAllContextExtensions
    {
        public static async Task<ImmutableArray<Diagnostic>> GetDiagnosticsInScopeAsync(this FixAllContext context)
        {
            switch (context.Scope)
            {
                case FixAllScope.Document:
                    return await context.GetDocumentDiagnosticsAsync(context.Document).ConfigureAwait(false);
                case FixAllScope.Project:
                    return await context.GetAllDiagnosticsAsync(context.Project).ConfigureAwait(false);
                case FixAllScope.Solution:
                    Solution solution = context.Solution;
                    ProjectDependencyGraph dependencyGraph = solution.GetProjectDependencyGraph();
 
                    // Walk through each project in topological order, determining and applying the diagnostics for each
                    // project.  We do this in topological order so that the compilations for successive projects are readily
                    // available as we just computed them for dependent projects.  If we were to do it out of order, we might
                    // start with a project that has a ton of dependencies, and we'd spend an inordinate amount of time just
                    // building the compilations for it before we could proceed.
                    //
                    // By processing one project at a time, we can also let go of a project once done with it, allowing us to
                    // reclaim lots of the memory so we don't overload the system while processing a large solution.
                    //
                    // Note: we have to filter down to projects of the same language as the FixAllContext points at a
                    // CodeFixProvider, and we can't call into providers of different languages with diagnostics from a
                    // different language.
                    IEnumerable<Project?> sortedProjects = dependencyGraph.GetTopologicallySortedProjects(context.CancellationToken)
                                                        .Select(solution.GetProject)
                                                        .Where(p => p.Language == context.Project.Language);
                    return (await Task.WhenAll(sortedProjects.Select(context.GetAllDiagnosticsAsync)).ConfigureAwait(false)).SelectMany(diag => diag).ToImmutableArray();
                default:
                    return ImmutableArray<Diagnostic>.Empty;
            }
        }
 
        public static async Task<ImmutableArray<Project>> GetProjectsWithDiagnosticsAsync(this FixAllContext context)
        {
            switch (context.Scope)
            {
                case FixAllScope.ContainingMember:
                case FixAllScope.ContainingType:
                case FixAllScope.Document:
                case FixAllScope.Project:
                    return ImmutableArray.Create(context.Project);
                case FixAllScope.Solution:
                    ImmutableArray<Project>.Builder projectsWithDiagnostics = ImmutableArray.CreateBuilder<Project>();
                    foreach (var project in context.Solution.Projects)
                    {
                        ImmutableArray<Diagnostic> diagnostics = await context.GetAllDiagnosticsAsync(project).ConfigureAwait(false);
                        if (diagnostics.Length != 0)
                        {
                            projectsWithDiagnostics.Add(project);
                        }
                    }
                    return projectsWithDiagnostics.ToImmutable();
                default:
                    return ImmutableArray<Project>.Empty;
            }
        }
    }
}