File: Microsoft.NetCore.Analyzers\Runtime\CSharpPreferDictionaryContainsMethods.Fixer.cs
Web Access
Project: src\src\sdk\src\Microsoft.CodeAnalysis.NetAnalyzers\src\Microsoft.CodeAnalysis.CSharp.NetAnalyzers\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.csproj (Microsoft.CodeAnalysis.CSharp.NetAnalyzers)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.NetCore.Analyzers.Runtime;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Threading.Tasks;
using System.Threading;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.NetCore.Analyzers;
using Analyzer.Utilities.Extensions;
using Analyzer.Utilities;

namespace Microsoft.NetCore.CSharp.Analyzers.Runtime
{
    [ExportCodeFixProvider(LanguageNames.CSharp)]
    public sealed class CSharpPreferDictionaryContainsMethodsFixer : PreferDictionaryContainsMethodsFixer
    {
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Document doc = context.Document;
            SyntaxNode root = await doc.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            if (root.FindNode(context.Span) is not InvocationExpressionSyntax invocation)
                return;
            if (invocation.Expression is not MemberAccessExpressionSyntax containsMemberAccess)
                return;
            if (containsMemberAccess.Expression.WalkDownParentheses() is not MemberAccessExpressionSyntax keysOrValuesMemberAccess)
                return;

            if (keysOrValuesMemberAccess.Name.Identifier.ValueText == PreferDictionaryContainsMethods.KeysPropertyName)
            {
                string codeFixTitle = MicrosoftNetCoreAnalyzersResources.PreferDictionaryContainsKeyCodeFixTitle;
                var action = CodeAction.Create(codeFixTitle, ct => ReplaceMethodNameAsync(PreferDictionaryContainsMethods.ContainsKeyMethodName, ct), codeFixTitle);
                context.RegisterCodeFix(action, context.Diagnostics);
            }
            else if (keysOrValuesMemberAccess.Name.Identifier.ValueText == PreferDictionaryContainsMethods.ValuesPropertyName)
            {
                string codeFixTitle = MicrosoftNetCoreAnalyzersResources.PreferDictionaryContainsValueCodeFixTitle;
                var action = CodeAction.Create(codeFixTitle, ct => ReplaceMethodNameAsync(PreferDictionaryContainsMethods.ContainsValueMethodName, ct), codeFixTitle);
                context.RegisterCodeFix(action, context.Diagnostics);
            }

            return;

            //  Local functions.

            async Task<Document> ReplaceMethodNameAsync(string methodName, CancellationToken ct)
            {
                var editor = await DocumentEditor.CreateAsync(doc, ct).ConfigureAwait(false);
                var containsMemberAccess = editor.Generator.MemberAccessExpression(keysOrValuesMemberAccess.Expression, methodName);
                var newInvocation = editor.Generator.InvocationExpression(containsMemberAccess, invocation.ArgumentList.Arguments);
                editor.ReplaceNode(invocation, newInvocation);

                return editor.GetChangedDocument();
            }
        }
    }
}