File: HideBaseCodeFixProvider.AddNewKeywordAction.cs
Web Access
Project: ..\..\..\src\CodeStyle\CSharp\CodeFixes\Microsoft.CodeAnalysis.CSharp.CodeStyle.Fixes.csproj (Microsoft.CodeAnalysis.CSharp.CodeStyle.Fixes)
// 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.Linq;
using System.Threading.Tasks;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.OrderModifiers;
using Microsoft.CodeAnalysis.OrderModifiers;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis.CSharp.LanguageService;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.CodeActions;
 
namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.HideBase
{
    internal partial class HideBaseCodeFixProvider
    {
        private class AddNewKeywordAction : CodeAction
        {
            private readonly Document _document;
            private readonly SyntaxNode _node;
            private readonly CodeActionOptionsProvider _fallbackOptions;
 
            public override string Title => CSharpCodeFixesResources.Hide_base_member;
 
            public AddNewKeywordAction(Document document, SyntaxNode node, CodeActionOptionsProvider fallbackOptions)
            {
                _document = document;
                _node = node;
                _fallbackOptions = fallbackOptions;
            }
 
            protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
            {
                var root = await _document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
                var options = await _document.GetCSharpCodeFixOptionsProviderAsync(_fallbackOptions, cancellationToken).ConfigureAwait(false);
 
                var newNode = GetNewNode(_node, options.PreferredModifierOrder.Value);
                var newRoot = root.ReplaceNode(_node, newNode);
 
                return _document.WithSyntaxRoot(newRoot);
            }
 
            private static SyntaxNode GetNewNode(SyntaxNode node, string preferredModifierOrder)
            {
                var syntaxFacts = CSharpSyntaxFacts.Instance;
                var modifiers = syntaxFacts.GetModifiers(node);
                var newModifiers = modifiers.Add(SyntaxFactory.Token(SyntaxKind.NewKeyword));
 
                if (!CSharpOrderModifiersHelper.Instance.TryGetOrComputePreferredOrder(preferredModifierOrder, out var preferredOrder) ||
                    !AbstractOrderModifiersHelpers.IsOrdered(preferredOrder, modifiers))
                {
                    return syntaxFacts.WithModifiers(node, newModifiers);
                }
 
                var orderedModifiers = new SyntaxTokenList(
                    newModifiers.OrderBy(CompareModifiers));
 
                return syntaxFacts.WithModifiers(node, orderedModifiers);
 
                int CompareModifiers(SyntaxToken left, SyntaxToken right)
                    => GetOrder(left) - GetOrder(right);
 
                int GetOrder(SyntaxToken token)
                    => preferredOrder.TryGetValue(token.RawKind, out var value) ? value : int.MaxValue;
            }
        }
    }
}