File: CodeRefactorings\EnableNullable\EnableNullableCodeRefactoringProvider.FixAllProvider.cs
Web Access
Project: ..\..\..\src\Features\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.Features.csproj (Microsoft.CodeAnalysis.CSharp.Features)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.Shared.Extensions;
using FixAllScope = Microsoft.CodeAnalysis.CodeFixes.FixAllScope;
 
namespace Microsoft.CodeAnalysis.CSharp.CodeRefactorings.EnableNullable
{
    internal partial class EnableNullableCodeRefactoringProvider : CodeRefactoringProvider
    {
        internal sealed override CodeAnalysis.CodeRefactorings.FixAllProvider? GetFixAllProvider()
            => FixAllProvider.Instance;
 
        private sealed class FixAllProvider : CodeAnalysis.CodeRefactorings.FixAllProvider
        {
            public static readonly FixAllProvider Instance = new();
 
            private FixAllProvider()
            {
            }
 
            public override IEnumerable<FixAllScope> GetSupportedFixAllScopes()
                => ImmutableArray.Create(FixAllScope.Solution);
 
            public override Task<CodeAction?> GetFixAsync(FixAllContext fixAllContext)
            {
                Debug.Assert(fixAllContext.Scope == FixAllScope.Solution);
                return Task.FromResult<CodeAction?>(new FixAllCodeAction(EnableNullableReferenceTypesInSolutionAsync));
 
                async Task<Solution> EnableNullableReferenceTypesInSolutionAsync(CodeActionPurpose purpose, CancellationToken cancellationToken)
                {
                    var solution = fixAllContext.Solution;
                    foreach (var projectId in solution.ProjectIds)
                    {
                        var project = solution.GetRequiredProject(projectId);
                        if (!ShouldOfferRefactoring(project))
                            continue;
 
                        solution = await EnableNullableReferenceTypesAsync(project, purpose,
                            fixAllContext.GetOptionsProvider(), fixAllContext.CancellationToken).ConfigureAwait(false);
                    }
 
                    return solution;
                }
            }
 
            private sealed class FixAllCodeAction : CodeAction.SolutionChangeAction
            {
                private readonly Func<CodeActionPurpose, CancellationToken, Task<Solution>> _createChangedSolution;
 
                public FixAllCodeAction(Func<CodeActionPurpose, CancellationToken, Task<Solution>> createChangedSolution)
                : base(
                    CSharpFeaturesResources.Enable_nullable_reference_types_in_solution,
                    cancellationToken => createChangedSolution(CodeActionPurpose.Apply, cancellationToken),
                    nameof(CSharpFeaturesResources.Enable_nullable_reference_types_in_solution))
                {
                    _createChangedSolution = createChangedSolution;
                }
 
                protected override async Task<IEnumerable<CodeActionOperation>> ComputePreviewOperationsAsync(CancellationToken cancellationToken)
                {
                    var changedSolution = await _createChangedSolution(CodeActionPurpose.Preview, cancellationToken).ConfigureAwait(false);
                    if (changedSolution is null)
                        return Array.Empty<CodeActionOperation>();
 
                    return new CodeActionOperation[] { new ApplyChangesOperation(changedSolution) };
                }
            }
        }
    }
}