File: Microsoft.NetCore.Analyzers\Runtime\SpecifyCultureForToLowerAndToUpper.Fixer.cs
Web Access
Project: src\sdk\src\Microsoft.CodeAnalysis.NetAnalyzers\src\Microsoft.CodeAnalysis.NetAnalyzers\Microsoft.CodeAnalysis.NetAnalyzers.csproj (Microsoft.CodeAnalysis.NetAnalyzers)
// 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.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Analyzer.Utilities;
using Analyzer.Utilities.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Editing;

namespace Microsoft.NetCore.Analyzers.Runtime
{
    public abstract class SpecifyCultureForToLowerAndToUpperFixerBase : CodeFixProvider
    {
        public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(SpecifyCultureForToLowerAndToUpperAnalyzer.RuleId);

        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var root = await context.Document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
            var node = root.FindNode(context.Span);

            if (ShouldFix(node))
            {
                var generator = SyntaxGenerator.GetGenerator(context.Document);

                var title = MicrosoftNetCoreAnalyzersResources.SpecifyCurrentCulture;
                context.RegisterCodeFix(CodeAction.Create(title,
                                                         async ct => await SpecifyCurrentCultureAsync(context.Document, generator, root, node, ct).ConfigureAwait(false),
                                                         equivalenceKey: nameof(MicrosoftNetCoreAnalyzersResources.SpecifyCurrentCulture)),
                                        context.Diagnostics);

                title = MicrosoftNetCoreAnalyzersResources.UseInvariantVersion;
                context.RegisterCodeFix(CodeAction.Create(title,
                                                         async ct => await UseInvariantVersionAsync(context.Document, generator, root, node).ConfigureAwait(false),
                                                         equivalenceKey: nameof(MicrosoftNetCoreAnalyzersResources.UseInvariantVersion)),
                                        context.Diagnostics);
            }
        }

        protected abstract bool ShouldFix(SyntaxNode node);

        protected abstract Task<Document> SpecifyCurrentCultureAsync(Document document, SyntaxGenerator generator, SyntaxNode root, SyntaxNode node, CancellationToken cancellationToken);

        protected static SyntaxNode CreateCurrentCultureMemberAccess(SyntaxGenerator generator, SemanticModel model)
        {
            var cultureInfoType = model.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemGlobalizationCultureInfo)!;
            return generator.MemberAccessExpression(
                generator.TypeExpressionForStaticMemberAccess(cultureInfoType),
                generator.IdentifierName("CurrentCulture"));
        }

        protected abstract Task<Document> UseInvariantVersionAsync(Document document, SyntaxGenerator generator, SyntaxNode root, SyntaxNode node);

        protected static string GetReplacementMethodName(string currentMethodName) => currentMethodName switch
        {
            SpecifyCultureForToLowerAndToUpperAnalyzer.ToLowerMethodName => "ToLowerInvariant",
            SpecifyCultureForToLowerAndToUpperAnalyzer.ToUpperMethodName => "ToUpperInvariant",
            _ => currentMethodName,
        };

        public sealed override FixAllProvider GetFixAllProvider()
        {
            return WellKnownFixAllProviders.BatchFixer;
        }
    }
}